Using accepts_nested_attributes_for, has_many and creating just one entry

Go To StackoverFlow.com

4

I have a Page with many Comments. Many users can access this page and submit comments. I view the comments on another Page that is private.

models/page.rb

class Page < ActiveRecord::Base
  has_many :comments, :dependent => :destroy 
  accepts_nested_attributes_for :comments, :allow_destroy => true
end

models/comment.rb

class Comment < ActiveRecord::Base
  belongs_to :page
  belongs_to :user
end

views/pages/show.html.erb relevant section

<%= form_for @page, :remote => true do |f| %>
    <% f.fields_for :comments do |builder| %>
   <%= builder.text_area :content, :rows => 1 %>
   <%= builder.submit "Submit" %>
    <% end %>
<% end %>

controllers/pages_controller.rb

def show
  @page = Page.find(params[:id])
end

def update
  @page = Page.find(params[:id])
  @page.comments.build
  @page.update_attributes(params[:page])
end

The issue here is that I do not want to have the user see multiple fields for comments. Yet, if I do <% f.fields_for :comment do |builder| %> then it throws an error because it doesn't know what one comment is, and only wants to deal with multiple.

Essentially, the user should be able to submit a single comment on a page, which has many comments, and have that automatically associated with the page. As a secondary thing, I need to have the user's id (accessible through current_user.id via Devise) associated with the comment.

2012-04-04 20:05
by tibbon


9

<% f.fields_for :comments, f.object.comments.build do |fc| %>
  <!-- rest of form -->
<% end %>
2012-04-04 20:28
by Alex Bartlow
This seemed to do the trick. I'd never have thought of that syntax before - tibbon 2012-04-04 20:32
I agree with Alex Bartlow's comment. Here are the relevant api docs: http://apidock.com/rails/v3.1.0/ActionView/Helpers/FormHelper/fields_for Search through that page for "It’s also possible to specify the instance to be used" and you'll see the code example for it.

Also, to add in the userid into the comments form, use a hiddenfieldtag: fc.hidden_field :user_id, current_user.id. Here are the docs: http://apidock.com/rails/ActionView/Helpers/FormHelper/hiddenfiel - Dylan Cashman 2012-04-05 14:30

This trick save my day, thanks a lot - Cam Song 2014-03-19 09:52


0

could you use nested resources? basically in the routes.rb...

resources :pages do 
  resources :comments 
end     

then in the comments controller you can find the pages by page_id or something like that.. Don't recall exact syntax off top of head..

2012-04-04 20:27
by Gary Pinkham
Ads