0

I'm rendering a partial that renders a form, using ajax (I can't just render the form directly). Posting a comment works fine when I'm rendering the form without ajax but with ajax it seems the partial can't access the @post variable.

<%= link_to "Render form", submit_comment_path, :remote => true  %>

<div id="form">
</div>

I have a submit_comment.js file that looks like this:

$("#form").html("<%= j render(partial: 'comment_partial', locals: {post: @post}) %>");

The comment_partial view:

<%= render 'comments/form' %>

The form view:

<%= simple_form_for [post, Comment.new] %>

...

The submit_comment_path route:

 get  '/submit_comment', to: 'posts#submit_comment', as: :submit_comment

The posts controller (it's being rendered on the show page):

def show
  @post = Post.find(params[:id])    
end

def submit_comment
 respond_to do |format|
  format.html
  format.js
 end
end

and the comments controller:

def create
 @post = Post.find(params[:post_id])
end

If I try to post a new comment it gives me a routing error and takes me to /posts//comment. Putting post.id in the comment_partial gives me an undefined error.

1 Answer 1

1

The big piece of the puzzle is understanding that instance variables (@post in this instance) disappear as soon as the Controller renders anything.

You correctly assign @post when you render the show page:

def show
  @post = Post.find(params[:id])    
end

However, @post disappears the second that show.html.erb is done rendering. When you click on the link to hit the submit comment method, no @post is getting created...

def submit_comment
 # No instance variables here! :(
 respond_to do |format|
  format.html
  format.js
 end
end

Which means that the submit_comment.js file has no idea which post to be generating a form for.

However, it's not as simple as just throwing another Post.find(params[:id]) into the submit_comment method. You need to:

  1. Define a route that relies on post id
  2. Change the link in show.html.erb to include a specific @post.id
  3. Then find the corresponding post to create a comment for.

It might look something like this...

routes.rb

...
resources :posts do
  member do
    get 'submit_comment'
  end
end
...

Read up on member routes at the Rails Guide. There are other ways of accomplishing a similar route.

posts/show.html.erb

<%= link_to "Render form", submit_comment_post_url(@post), :remote => true  %>

Note that the Rails default url helper is different than the one you've got, if you use member routes.

posts_controller.rb

def submit_comment
  @post = Post.find(params[:id])
  ...
end 

Hope that helps! Happy form-ing!

Sign up to request clarification or add additional context in comments.

1 Comment

You bet! So glad I could help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.