Question

attr_accessible marks all non specified attributes as protected, but I need for a few key attributes to still be written on create, as supported by attr_readonly.

I have my model setup like so:

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

The obvious workaround here would be to not use attr_readonly, create the object without the key attributes, then set and save them afterwards. The downside to this approach is that I now have at least 2 writes, and this create method needs to be as performant as humanly possible.

@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

How can I achieve the creation of the object with accessible attributes AND readonly attributes in 1 write without triggering a Can't mass-assign protected attributes error, while still enjoying the benefits of the readonly protection after creation?

Was it helpful?

Solution 2

You can substitute Foo.create with Foo.new.

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

You can also set :shiz as both attr_accessible and attr_readonly.

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

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

If you now try to modify :shiz it will not change (as it is readonly):

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

OTHER TIPS

Edit: see Mass assignment security

replace

attr_accessible :bar, :baz

with

attr_accessible :bar, :baz, :shiz
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top