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_idon_wishlist 定义为单独的字段。您使用对象形式 f.

定义的其他字段

你可以看到params被发送到服务器,你只有:

"review"=>{"rating"=>"5", "review_text"=>"What a good beer"}

因此,您的对象 @review 只能更新这些字段。 review_params 实际上是 params[:review].

所以如果你想更新beer_idon_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]' %>