同时使用attr_accessible和attr_readonly不允许创建记录

时间:2013-02-06 03:39:21

标签: ruby-on-rails performance rails-activerecord mass-assignment

attr_accessible将所有未指定的属性标记为受保护,但我仍需要在创建时写入一些关键属性,如attr_readonly所支持。

我的模型设置如下:

class Foo < ActiveRecord::Base
  attr_accessible :bar, :baz
  attr_readonly :shiz
end

class FooParent < ActiveRecord::Base
  has_many :foos
end

@foo_parent.foos.build(:bar => 1, :baz => 2, :shiz => 3)     # Can't mass-assign protected attribute: :shiz

这里明显的解决方法是不使用attr_readonly,创建没有键属性的对象,然后设置并保存它们。这种方法的缺点是我现在至少有2次写入,这种创建方法需要尽可能高效。

@foo_parent.foos.build(:bar => 1, :baz => 2)                 # write #1
@foo_parent.foos.each do |f|
  f.update_attribute(:baz, 3)                                # write #2 and more
end

如何在不写入Can't mass-assign protected attributes错误的情况下,在1次写入中实现具有可访问属性和只读属性的对象的创建,同时仍然享受创建后的只读保护的好处?

2 个答案:

答案 0 :(得分:4)

修改:请参阅Mass assignment security

替换

attr_accessible :bar, :baz

attr_accessible :bar, :baz, :shiz

答案 1 :(得分:3)

您可以将Foo.create替换为Foo.new

f = Foo.new(:bar => 1, :baz => 2)             # no write
f.update_attribute(:shiz, 3)                     # write 1

您还可以将:shiz设置为 attr_accessibleattr_readonly

attr_accessible :bar, :baz, :shiz
attr_readonly :shiz

f = Foo.create(bar: 1, baz: 2, shiz: 3)        # write 1

如果您现在尝试修改:shiz,它将不会更改(因为它是只读):

f.update_attribute(:shiz, 15)
f.reload
f.shiz
=> 3