Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting Rails model attributes order

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.

like image 674
awilkening Avatar asked Sep 05 '12 02:09

awilkening


1 Answers

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.

like image 71
rubyruy Avatar answered Nov 08 '22 19:11

rubyruy