26

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

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

4

7 回答 7

66

几件事:

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

@user = User.create({:name => "My name", :user_type => "nice_user"})

但是,Rails 包含一些基本的安全规则,这意味着默认情况下并非所有属性都可以这样分配。您必须事先指定哪些可以。你这样做:

class User < ActiveRecord::Base
  attr_accessible :name, :user_type
end

如果您没有指定属性 is 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/

于 2012-05-13T20:38:21.920 回答
7

您是否正在使用 Rails 3.2,同时遵循 3.1 教程,例如 Pragmatic Programmer 的“Agile Web Development with Rails”第 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

......你很高兴继续学习。请记住在编写您的第一个生产应用程序时保持这一点:)

于 2012-07-19T16:43:41.190 回答
5
  1. 请尝试:打开config/application.rb

  2. 找到线config.active_record.whitelist_attributes = true

  3. 将真改为假

那你就没事了。

PS:记得重启rails控制台。

于 2013-12-11T03:31:01.720 回答
2

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

于 2013-12-11T03:58:10.163 回答
1

我不使用whitelist_attributes,因为我确实希望允许批量分配的用例用于我的内部逻辑,通常不直接在控制器中用于 CRUD 操作。我建议在这些情况下使用强参数。但是,当您想为特定模型启用批量分配时,您可以

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

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

于 2014-06-05T07:30:12.243 回答
0

这里有一些关于 Rails 中的质量分配是什么以及为什么要进行保护的信息。当您确实想要分配受保护的属性时,这很容易解决,但它需要几行额外的代码。

hassle = rota.hassles.build(:sender => user1, :receiver => user2)
hassle.type = 'sms'
hassle.save
于 2012-05-13T20:31:03.790 回答
0

你需要attr_accesible在你的模型类中

class <model_name> < ActiveRecord::Base
    attr_accessible :<fields_name>
end
于 2021-08-24T06:48:00.100 回答