简体   繁体   English

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

[英]ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes

If I try to execute the following code: 如果我尝试执行以下代码:

hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms")

I obain the following error: 我听到以下错误:

Failure/Error: hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms")
 ActiveModel::MassAssignmentSecurity::Error:
   Can't mass-assign protected attributes: type

I am not sure what this means. 我不确定这意味着什么。 I have made the :type to be compulsory, so if I do remove it, I get an sql error. 我已经使:type是必须的,所以如果我删除它,我得到一个SQL错误。

A couple things: 几件事:

Mass Assignment usually means passing attributes into the call that creates an object as part of an attributes hash . 质量赋值通常意味着将属性传递给调用,该调用将对象创建为属性哈希的一部分。 That is, you pass a bunch of attributes in a hash into the call that creates the new object. 也就是说,您将哈希中的一堆属性传递给创建新对象的调用。 For example: 例如:

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

However, Rails includes some basic security rules that mean not all attributes can be assigned that way by default . 但是,Rails包含一些基本的安全规则,这意味着默认情况下不能以这种方式分配所有属性 You have to specify which ones can beforehand. 您必须事先指定哪些可以。 You do so like this: 你这样做:

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

If you don't specify an attribute is attr_accessible , and you pass it in to create the object, you get the error you posted. 如果未指定属性为attr_accessible ,并且将其传递给创建对象,则会收到您发布的错误。

Here are more details: 这里有更多细节:

http://api.rubyonrails.org/v3.2.9/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html http://api.rubyonrails.org/v3.2.9/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

The alternative is to set some of the attributes when you first create the record, and set others after -- like so: 另一种方法是在第一次创建记录时设置一些属性,然后在其后设置其他属性 - 如下所示:

# 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

In addition, if you're having issues with using the column name type because rails is getting confused and thinks you want to use Single Table Inheritance (STI), check the answer to this question to see how to get around it: http://guides.rubyonrails.org/ 此外,如果您在使用列名称type遇到问题,因为rails感到困惑并且认为您想要使用单表继承(STI),请检查此问题的答案以了解如何解决它: http:/ /guides.rubyonrails.org/

Are you working with Rails 3.2 while following a 3.1 tutorial such as the Pragmatic Programmer's "Agile Web Development with Rails" 4th edition? 您是否正在使用Rails 3.2,同时遵循3.1教程,例如Pragmatic Programmer的“使用Rails进行敏捷Web开发”第4版? Then check http://guides.rubyonrails.org/3_2_release_notes.html . 然后查看http://guides.rubyonrails.org/3_2_release_notes.html

Your problem is that from Rails 3.1 to 3.2 checking of mass assignment protection for Active Record models is set to 'strict' by default. 您的问题是从Rails 3.1到3.2默认情况下,Active Record模型的质量分配保护检查设置为“严格”。 Comment out the appropriate lines in these files: 注释掉这些文件中的相应行:

config/environments/development.rb
config/environments/test.rb

... and you're good to go on learning. ......你很高兴继续学习。 Remember to leave this in effect when coding your first production application :) 在编写第一个生产应用程序时,请记住保持这种效果:)

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

  2. Locate the line of config.active_record.whitelist_attributes = true 找到config.active_record.whitelist_attributes = true的行

  3. Change true to false 将true更改为false

Then you shall be fine. 那你就没事了。

PS: remember to restart the rails console. PS:记得重新启动rails控制台。

You should be getting another error, like this: column 'type' is reserved for storing the class in case of inheritance. 您应该收到另一个错误,如下所示:列'type'保留用于在继承的情况下存储类。 Because Column 'type' should not be used in active record database. 因为列'类型'不应在活动记录数据库中使用。

I do not use whitelist_attributes since use cases when I do want to allow mass-assignment are for my internal logic and usually not directly in Controller for CRUD actions. 我不使用whitelist_attributes因为我希望允许批量分配的用例是我的内部逻辑,通常不直接在Controller中进行CRUD操作。 I suggest using strong params in those cases. 我建议在这些情况下使用强对数。 But when you want to enable mass-assignment for specific model you do 但是当你想为特定模型启用质量分配时

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

This basically sets attr_protected to empty array ([]) 这基本上将attr_protected设置为空数组([])

Here is some info on what mass assignment in Rails is, and why the protection is in place. 以下是有关Rails中的质量分配以及保护措施的原因的一些信息。 It's pretty easy to get around when you really do want to assign a protected attribute, but it takes a couple of extra lines. 当你真的想要分配一个受保护的属性时,它很容易解决,但它需要额外的几行。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM