Search code examples
ruby-on-railsrubyrestviewformbuilder

form_for with association - how to provide parent id?


Assuming the Post - Comment model with the nested resources:

resources :posts do
  resources :comments
end

How should the app/views/comments/_form.html.haml (erb will do as well) look like so that it also provides id of the post to attach the comment to?

Current only one way I know is to manually add hidden input with the post id. It looks dirty to me.

Is there any better way? I expected rails to understand the nested resource and automatically include the post_id as a hidden input.

= form_for [@post, @comment] do |f|
  .field
    f.label :body
    f.text_field :body
    hidden_field_tag :post_id, @post.id
  .actions
    = f.submit 'Save'

EDIT: Using Mongoid, not ActiveRecord.

Thanks.


Solution

  • The ID of the post will actually be in the URL. If you type rake routes into your terminal/console, you will see that the pattern for your nested resource is defined as such:

    POST    /posts/:post_id/comments    {:controller=>"comments", :action=>"create"}
    

    Take a look at the HTML that is spit out by the form_for method, and look specifically at the action url of the <form> tag. You should see something like action="/posts/4/comments".

    Assuming that you've defined resources :comments only once in your routes.rb, as a nested resource of resources :posts, then it is safe for you to modify the CommentsController#create action as such:

    # retrieve the post for this comment
    post = Post.find(params[:post_id])
    comment = Comment.new(params[:comment])
    comment.post = post
    

    Or you can simply pass params[:post_id] to comment instance like so:

    comment.post_id = params[:post_id]
    

    I hope this helps.

    For more information on nested forms/models, I recommend watching the following Railscasts: