Rails 模型的一些属性没有被 update_attributes 方法更新
Some attributes of Rails model not being updated by update_attributes method
刚开始使用 Rails 4.1,我很难理解当我尝试使用 update_attributes 方法更新模型时发生的事情。我写了一个小应用程序来学习如何让用户评论啤酒。用户可以使用如下形式编辑他们的评论:
<%= form_for review do |f| %>
<%= f.label :rating %>
<%= f.select :rating, 1..5%>
<%= f.label :review_text %>
<%= f.text_area :review_text %>
<%= hidden_field_tag :beer_id, @beer.id %>
<%= hidden_field_tag :on_wishlist, "f" %>
<%= f.submit %>
<% end %>
控制器有一个简单的更新操作,如下所示:
@review.update_attributes(review_params)
参数如下所示:
def review_params
params.require(:review).permit(:rating, :user_id, :beer_id, :review_text, :on_wishlist)
end
一切都很简单。我不明白的是为什么这只适用于更新一些属性。特别是,on_wishlist 属性不会更新。如果我查看服务器日志,我会看到以下内容:
Parameters: { ... "review"=>{"rating"=>"5", "review_text"=>"What a good beer"}, "beer_id"=>"4", "on_wishlist"=>"f", "commit"=>"Update Review", "id"=>"7"}
...
SQL (0.5ms) UPDATE "reviews" SET "rating" = ?, "review_text" = ?, "updated_at" = ? WHERE "reviews"."id" = 7 [["rating", 5], ["review_text", "What a good beer"], ["updated_at", "2015-01-15 22:51:56.009256"]]
所以我可以看到 on_wishlist 隐藏字段正在发送到服务器,只是没有包含在更新中,即使它在 review_params 哈希中也是如此。
如果我将控制器代码更改为以下,它工作正常:
@review.update_attributes(review_params)
@review.on_wishlist = params[:on_wishlist]
@review.save
但我不明白为什么 on_wishlist 必须分开处理。我能想到的唯一相关细节是 on_wishlist 是在与其余评论分开的迁移中添加的,如下所示:
class AddOnWishlistToReviews < ActiveRecord::Migration
def change
add_column :reviews, :on_wishlist, :bool, :default => false
end
end
我确定我遗漏了一些简单的东西 -- 感谢您的帮助。
这是因为您在表单中将 beer_id
和 on_wishlist
定义为单独的字段。您使用对象形式 f
.
定义的其他字段
你可以看到params被发送到服务器,你只有:
"review"=>{"rating"=>"5", "review_text"=>"What a good beer"}
因此,您的对象 @review
只能更新这些字段。 review_params
实际上是 params[:review]
.
所以如果你想更新beer_id
和on_wishlist
,你可以使用f
对象使这些字段属于表单中的对象:
<%= f.hidden_field :beer_id, value: @beer.id %>
<%= f.hidden_field :on_wishlist, value: "f" %>
或更改他们的名称:
<%= hidden_field_tag :beer_id, @beer.id, name: 'review[beer_id]' %>
<%= hidden_field_tag :on_wishlist, "f", name: 'review[on_wishlist]' %>
刚开始使用 Rails 4.1,我很难理解当我尝试使用 update_attributes 方法更新模型时发生的事情。我写了一个小应用程序来学习如何让用户评论啤酒。用户可以使用如下形式编辑他们的评论:
<%= form_for review do |f| %>
<%= f.label :rating %>
<%= f.select :rating, 1..5%>
<%= f.label :review_text %>
<%= f.text_area :review_text %>
<%= hidden_field_tag :beer_id, @beer.id %>
<%= hidden_field_tag :on_wishlist, "f" %>
<%= f.submit %>
<% end %>
控制器有一个简单的更新操作,如下所示:
@review.update_attributes(review_params)
参数如下所示:
def review_params
params.require(:review).permit(:rating, :user_id, :beer_id, :review_text, :on_wishlist)
end
一切都很简单。我不明白的是为什么这只适用于更新一些属性。特别是,on_wishlist 属性不会更新。如果我查看服务器日志,我会看到以下内容:
Parameters: { ... "review"=>{"rating"=>"5", "review_text"=>"What a good beer"}, "beer_id"=>"4", "on_wishlist"=>"f", "commit"=>"Update Review", "id"=>"7"}
...
SQL (0.5ms) UPDATE "reviews" SET "rating" = ?, "review_text" = ?, "updated_at" = ? WHERE "reviews"."id" = 7 [["rating", 5], ["review_text", "What a good beer"], ["updated_at", "2015-01-15 22:51:56.009256"]]
所以我可以看到 on_wishlist 隐藏字段正在发送到服务器,只是没有包含在更新中,即使它在 review_params 哈希中也是如此。
如果我将控制器代码更改为以下,它工作正常:
@review.update_attributes(review_params)
@review.on_wishlist = params[:on_wishlist]
@review.save
但我不明白为什么 on_wishlist 必须分开处理。我能想到的唯一相关细节是 on_wishlist 是在与其余评论分开的迁移中添加的,如下所示:
class AddOnWishlistToReviews < ActiveRecord::Migration
def change
add_column :reviews, :on_wishlist, :bool, :default => false
end
end
我确定我遗漏了一些简单的东西 -- 感谢您的帮助。
这是因为您在表单中将 beer_id
和 on_wishlist
定义为单独的字段。您使用对象形式 f
.
你可以看到params被发送到服务器,你只有:
"review"=>{"rating"=>"5", "review_text"=>"What a good beer"}
因此,您的对象 @review
只能更新这些字段。 review_params
实际上是 params[:review]
.
所以如果你想更新beer_id
和on_wishlist
,你可以使用f
对象使这些字段属于表单中的对象:
<%= f.hidden_field :beer_id, value: @beer.id %>
<%= f.hidden_field :on_wishlist, value: "f" %>
或更改他们的名称:
<%= hidden_field_tag :beer_id, @beer.id, name: 'review[beer_id]' %>
<%= hidden_field_tag :on_wishlist, "f", name: 'review[on_wishlist]' %>