1

I have a nested attribute and I can display values, but it is not saving into database why?

I have a model review and I want to nest attribute comments

review migration file

class CreateReviews < ActiveRecord::Migration
  def change
    create_table :reviews do |t|
      t.belongs_to :reviewable, polymorphic: true
      t.timestamps
    end
    add_index :reviews, [:reviewable_id, :reviewable_type]

  end
end

review model

class Review < ActiveRecord::Base
  attr_accessible :rating, :user_id, :comments_attributes, :service
  has_many :comments, as: :commentable
  belongs_to :user
  belongs_to :reviewable, polymorphic: true

  accepts_nested_attributes_for :comments

end

comments migration file

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.text :content
      t.belongs_to :commentable, polymorphic: true
      t.integer :user_id
      t.timestamps
    end
    add_index :comments, [:commentable_id, :commentable_type]
  end
end

comment model

class Comment < ActiveRecord::Base
  attr_accessible :content, :user_id
  belongs_to :commentable, polymorphic: true
  belongs_to :user
  belongs_to :review
end

This is the form

<%= form_for [@reviewable, @review], :html => {:multipart => true} do |f| %>

  <%= f.fields_for :comments, @review.comments.build do |field| %>
    <%= field.label "Comment" %></div>
    <%= field.text_field :content %>
  <% end %>

  <%= f.submit %>
<% end %>

It displays the fields, but how come when I save, it doesn't save?

I tried to display like this:

<%= @review.comments %>

Here's my review controller

  def new
    @review = @reviewable.reviews.new
    @review.comments.build
  end

Thanks for your help!

EDIT:

Review controller: create method

  def create
    @review = @reviewable.reviews.new(params[:review])
    @review.user = current_user
    if @review.save
      redirect_to @reviewable, notice: "review created."
    else
      render :new
    end
  end
5
  • Please post the create method in your controller Commented Jun 14, 2013 at 3:25
  • @muttonlamb Hello! I have edited my post to include the create method. Is there anything wrong with it? Thanks! Commented Jun 14, 2013 at 3:31
  • I cant see any problem there. could you share your code if possible, I mean using any public repo? Commented Jun 14, 2013 at 4:25
  • you can also try to inspect the log, whats happening there, is there any comment created when you save review? Commented Jun 14, 2013 at 4:34
  • @Muntasim It seems like it is being committed into the database, but it doesn't save into reviews database, from my log it there's a insert into "reviews" and another insert into "comments" Commented Jun 14, 2013 at 4:47

2 Answers 2

0

There seems to be some muddled logic in your controller and views

  def new
    @review = @reviewable.reviews.new
    @review.comments.build
  end

Here you are calling @reviewable.reviews.new, but @reviewable doesn't yet exist. A more usual way of calling this would be Review.new

Next in your view you do this

<%= form_for [@reviewable, @review], :html => {:multipart => true} do |f| %>

  <%= f.fields_for :comments, @review.comments.build do |field| %>

This is passing @reviewable and @review to the form_for. This seems odd. With nesting you would normally only need to pass the top level instance variable i.e. @review.

Next, when you get to fields_for you are passing :comments and @review.comments.build. Generally speaking this should only require :comment, because you've already built the comment in the controller.

I would recommend that you review these two screencasts

http://railscasts.com/episodes/196-nested-model-form-part-1 http://railscasts.com/episodes/197-nested-model-form-part-2

There are also a number of Gems that handle the whole process of making things commentable very eloquently, they can be found here

https://www.ruby-toolbox.com/categories/rails_comments

I think the commentable Gems path is better because they are being worked on by a larger community and I think end up being better than personal creations in the long term.

Hope this helps...

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

Comments

-1

you need to replace the following

<%= f.fields_for :comments, @review.comments.build do |field| %>

to

<%= f.fields_for :comments, @review.comments do |field| %>

to see created comments in form. As you have @review.comments.build in new action. Otherwise you cant see the associated comments on editing review

3 Comments

If I remove the .build, then the field for comments disappears
you have to have @review.comments.build in new action as I mentioned and in edit action @review.comments.build if @review.comments.empty?
I do have @review.comments.build in new action (I didn't touch my previous code, which has it in there). I also added the last bits into edit action, same result. The field does not show up. Also, I forgot to mention but not sure if it matters.. This form is in views/reviews/_form.html.erb, but I have rendered this page inside views/users/reviews.html.erb

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.