ActiveModel :: MassAssignmentSecurity ::错误:无法批量分配受保护的属性
如果我尝试执行以下代码:
hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms")
我发现以下错误:
Failure/Error: hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms") ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: type
我不确定这意味着什么。 我已经使:type是必须的,所以如果我删除它,我得到一个SQL错误。
几件事:
质量分配通常意味着将属性传递给调用,该调用将对象创建为属性哈希的一部分。 也就是说,您将哈希中的一堆属性传递给创建新对象的调用。 例如:
@user = User.create({:name => "My name", :user_type => "nice_user"})
但是,Rails包含一些基本的安全规则,这意味着默认情况下不能以这种方式分配所有属性 。 您必须事先指定哪些可以。 你这样做:
class User < ActiveRecord::Base attr_accessible :name, :user_type end
如果未指定属性是attr_accessible
,并且您将其传入以创建对象,则会收到您发布的错误。
这里有更多细节:
http://api.rubyonrails.org/v3.2.9/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html
另一种方法是在第一次创建记录时设置一些属性,然后在其后设置其他属性 - 如下所示:
# In this example `user_type` is not attr_accessible so it needs to be set specifically @user = User.create({:name => "My name"}) @user.user_type = "nice_user" @user.save
此外,如果您在使用列名称type
遇到问题,因为rails感到困惑并且认为您想要使用单表inheritance(STI),请检查此问题的答案以了解如何解决它: http:/ /guides.rubyonrails.org/
您是否正在使用Rails 3.2,同时遵循3.1教程,例如Pragmatic Programmer的“使用Rails进行敏捷Web开发”第4版? 然后查看http://guides.rubyonrails.org/3_2_release_notes.html 。
您的问题是从Rails 3.1到3.2默认情况下,Active Record模型的质量分配保护检查设置为“严格”。 注释掉这些文件中的相应行:
config/environments/development.rb config/environments/test.rb
……你继续学习很好。 在编写第一个生产应用程序时,请记住保持这种效果:)
-
请尝试:打开
config/application.rb
-
找到
config.active_record.whitelist_attributes = true
的行 -
将true更改为false
那你就没事了。
PS:记得重新启动rails控制台。
你应该得到另一个错误,如下所示:列’type’保留用于存储inheritance的类。 因为列’类型’不应在活动记录数据库中使用。
我不使用whitelist_attributes
因为我想要允许批量分配的用例是我的内部逻辑,通常不直接在Controller中用于CRUD操作。 我建议在这些情况下使用强对数。 但是当你想为特定模型启用质量分配时
class Foo < ActiveRecord::Base # disables mass-assigment attr_protected end
这基本上将attr_protected
设置为空数组([])
这里有一些关于Rails中的质量分配以及为什么保护到位的信息。 当你真的想要分配一个受保护的属性时,它很容易解决,但它需要额外的几行。
hassle = rota.hassles.build(:sender => user1, :receiver => user2) hassle.type = 'sms' hassle.save