When defining a virtual setter method that relies on another method to be set, it appears that the order of the attributes being set in the hash matters. Is there a way around this while still mass-assigning attributes?
https://gist.github.com/3629539
EDIT
The condition in the real code, not shown in the example, is checking for the existence of an associated object. If the object exists, set a value. If not, ignore the value passed in. However, I am also using accepts_nested_attributes_for. So, the attribute hash may contain the attributes for the association. In which case, the object will exist.
{:name => 'Fred', :nested_attributes => {:color => 'red'}}
Name will not be set because the model will not exist.
{:nested_attributes => {:color => 'red'}, :name => 'Fred'}
accepts_nested_attributes_for will build a Nested instance, then set the attributes. When the name is to be set, the instance will exist and the nested attribute will be set.
Had a similar issue, and I came to the following reasonably generic solution:
def assign_attributes(new_attributes)
assign_first = new_attributes.extract!(:must_be_set_first, :must_also_be_set_first)
super(assign_first) unless assign_first.empty?
super(new_attributes)
end
Using super
with the extracted param values you need set first ensures you handle all the weird special cases for attribute assignment (is it a reference? a params hash? a multi-value param?). Calling assign_attributes
repeatedly with parts of a hash really should have the same effects as calling it with the whole hash once - this should be reasonably safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With