Koren Leslie Cohen

  • About
  • Blog
  • Contact

8 comments

Ruby / Rails

:remote => true in Rails Forms

December 2, 2014 by Koren Leslie Cohen

rails

Providing a seamless user experience often means removing the need to refresh a page when adding or removing content. This can be done by working with AJAX within your Rails application.

In the traditional Rails blog example where you have users, posts and comments, you may want to use :remote => true to add comments to posts without having to refresh the page. This can be accomplished in a few simple steps.

1. Add :remote => true to Your Form

Add :remote => true to your form, which should be included in a partial in views/comments and rendered in the show.html.erb page for views/posts:

<%= form_for [@post, Comment.new], :remote => true do |f| %>
  <div class="field">
    <%= f.text_area :content, class: "form-control col-lg-8", placeholder: "Provide comment here." %>
    <%= f.hidden_field :post_id, :value => @post.id %>
    <%= f.hidden_field :user_id, :value => current_user.id %>
  </div>
  <div class="actions">
    <%= f.submit "Leave Comment" %>
  </div>
<% end %>

You can render this form in your show page by including the following:

<%= render 'comments/new', review: Comment.new(post_id: @post.id) %>

Adding :remote => true to your form submits the data to your database without refreshing the page. However, this information will not automatically be rendered by the browser. Until you add the appropriate JavaScript to append this information to the DOM, you’ll have to refresh the page to see the information displayed (which defeats the purpose of using AJAX in the first place).

2. Update Your Controller

In your comments_controller.rb, update your create function to include format.js {}:

  # POST /comments
  # POST /comments.json
  def create
    @comment = Comment.new(comment_params)

    respond_to do |format|
      if @comment.save
        format.html { redirect_to @comment.post, notice: 'Comment was successfully created.' }
        format.js   { }
        format.json { render :show, status: :created, location: @comment }
      else
        format.html { render :new }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end
  end

This allows the create function to respond with the appropriate JavaScript.

3. Add create.js.erb File

Add a create.js.erb file in your views/comments directory:

# confirm file called
console.log("create.js.erb file");

# add new comment to end of comments section
$("#comments").append("<%= @comment.user.name %>: <%= @comment.content %>");

# remove current DOM element stating there are no comments yet (if no comments yet exist)
$("#comments h4").html(""); 

# replace comment form so user can only comment once (if desirable)
$(".comment_form").html("<h1>You have commented on this post</h1>");

You may see a 500 Internal Server Error, or your JavaScript file may not initially work. This is a common problem and usually due to a missing partial. You should review your logs to determine what is missing and what additional partials you may need to create.

  • About
  • Latest Posts
Connect
Koren Leslie Cohen
Product manager at Facebook. Former senior product manager at Dollar Shave Club in Los Angeles and software engineer at J.Crew / Madewell in New York City. Recovering trial lawyer.
Connect
Latest posts by Koren Leslie Cohen (see all)
  • PM Career Story - April 28, 2022
  • How to Transition into Product Management - December 26, 2017
  • What I’ve Learned in My First Few Months as a Product Manager - October 14, 2015

Related Posts

Rails: Uploading Photos via Amazon S3 and Paperclip
Ruby Classes

Share

Facebook Google+ Twitter Pinterest Email

Comments Cancel reply

Your email address will not be published. Required fields are marked *

*

code

  1. Avi says

    December 2, 2014 at 3:21 pm

    Pretty sure you don’t need:

    @post.id %>

    in your form as your using a nested form route.

    Reply
    • Koren Leslie Cohen says

      December 6, 2014 at 3:24 am

      The data does not persist in the app I’m working on if that is removed.

      Reply
  2. Mikel says

    March 9, 2015 at 2:59 am

    Me and this article, sitting in a tree, L-AE–R-N-I-N-G!

    Reply
    • Koren Leslie Cohen says

      March 17, 2015 at 5:06 pm

      Awesome.

      Reply
  3. Kiril says

    April 3, 2016 at 5:41 pm

    I’m not sure, but isn’t it possible with those hidden_fields to just change value of users id in html and write comments as other user?

    Reply
    • LEo Brown says

      January 26, 2017 at 5:20 pm

      I use a similar approach and had that concern. A simple solution: manually verify in the controller that current_user == @comment.user. If it’s false, I just redirect to root_url (not going to spend too much energy explaining the error in this scenario). There may be some way to do a validation in the model as well, but my controller approach seemed straightforward and reliable enough.

      Reply
  4. Randall says

    June 17, 2017 at 7:32 pm

    You’re missing Step 4: How to write a test to verify this is working :p

    Reply
  5. hubertlemurto says

    December 23, 2017 at 11:28 pm

    carpe diem

    Reply

Back to Blog

  • GitHub
  • Instagram
  • LinkedIn
  • RSS
  • Twitter

Looking for something?

Copyright 2023 Koren Leslie Cohen