2013-02-21 131 views
1

如何让Ruby(Rails)忽略在批量分配时存在的受保护变量?Ruby - 忽略受保护的属性

class MyClass < ActiveRecord::Base 
    attr_accessible :name, :age 
end 

现在我将批量分配一个散列来创建一个新的MyClass

MyClass.create!({:name => "John", :age => 25, :id => 2}) 

这会给我一个例外:

ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: id 

我想它来创建一个新的MyClass与指定的(无保护)的属性,而忽略了id属性。

附注:我怎样才能忽略未知属性。例如,MyClass没有location属性。如果我尝试大量分配它,就忽略它。

回答

2

设置mass_assignment_sanitizer:logger解决了开发和测试中的问题。

config.active_record.mass_assignment_sanitizer = :logger 
5

使用Hash#slice仅在分配选择你真正感兴趣的按键:

# Pass only :name and :age to create! 
MyClass.create!(params.slice(:name, :age)) 

通常情况下,我会为params添加包装方法到我的控制器,过滤下来,只说我知道的领域我想分配:

class MyController 

    # ... 

    def create 
    @my_instance = MyClass.create!(create_params) 
    end 

protected 

    def create_params 
    params.slice(:name, :age) 
    end 
end 
+2

那么,这就是整个问题。你只接受你*知道的变量。你*不知道的变量是曾经被削弱过的变量,你正在切出并使用你知道的变量。 – meagar 2013-02-21 17:48:44

+0

是的,你必须考虑你正在更新/创建时,你分配的东西。这就是为什么Rails在默认情况下将质量分配保护打开的原因。此解决方案仅分配您定义的变量,这应该是您想要的。 – 2013-02-21 17:50:34

+0

@MichaelPapile对。我如何获得某个类的无保护属性? – 2013-02-21 17:52:56

1

您可以使用strong_parameters的宝石,那将是在轨道4

见DOCUME ntation here

这样,您可以通过操作或角色指定所需的参数,例如。

+0

很高兴知道。现在,我需要一些简单的东西,而无需添加任何宝石。 – 2013-02-21 18:41:10

0

如果你想坐下和肮脏它,并动态地只让一个模型,通过属性,而不禁止全局::加载ActiveModel :: MassAssignmentSecurity错误:

params = {:name => "John", :age => 25, :id => 2} 
MyClass.create!(params.slice(*MyClass.new.attributes.symbolize_keys.keys) 

的.symbolize_keys是必需的如果你在散列中使用符号,就像在这种情况下一样,但你可能不需要这样做。