ActiveModel :: MassAssignmentSecurity ::错误:无法批量分配受保护的属性

时间:2012-05-13 20:25:38

标签: ruby-on-rails activemodel

如果我尝试执行以下代码:

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错误。

6 个答案:

答案 0 :(得分:63)

一些事情:

批量分配通常意味着将属性传递给调用,该调用将对象创建为属性哈希的一部分。也就是说,您将哈希中的一堆属性传递给创建新对象的调用。例如:

@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感到困惑并认为您想要使用单表继承(STI),请检查此问题的答案以查看如何解决它:http://guides.rubyonrails.org/

答案 1 :(得分:7)

您是否正在使用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

......你继续学习很好。在编写第一个生产应用程序时,请记住保持这种效果:)

答案 2 :(得分:5)

  1. 请尝试:打开config/application.rb

  2. 找到config.active_record.whitelist_attributes = true

  3. 的行
  4. 将true更改为false

  5. 那你就没事了。

    PS:记得重新启动rails控制台。

答案 3 :(得分:2)

你应该得到另一个错误,如下所示:列'type'保留用于在继承的情况下存储类。因为列'类型'不应在活动记录数据库中使用。

答案 4 :(得分:1)

我不使用whitelist_attributes,因为我想要允许批量分配的用例是我的内部逻辑,通常不直接在Controller中用于CRUD操作。我建议在这些情况下使用强对数。但是,如果要为特定模型启用质量分配,则执行

class Foo < ActiveRecord::Base
  # disables mass-assigment
  attr_protected
end

这基本上将attr_protected设置为空数组([])

答案 5 :(得分:0)

Here是关于Rails中的质量分配是什么以及为什么保护到位的一些信息。当你真的想要分配一个受保护的属性时,它很容易出现,但它需要额外的几行。

hassle = rota.hassles.build(:sender => user1, :receiver => user2)
hassle.type = 'sms'
hassle.save