问题
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
回答1:
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...
回答2:
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
来源:https://stackoverflow.com/questions/17100462/nested-attributes-not-saving-in-database-does-not-display-values-ruby-on-rail