Setting Rails Model Attributes

When defining a virtual setter method that relies on another method to be set up, it seems that the order of the attributes specified in the hashing matters. Is there a way around this while the mass assignment attributes are still there?

https://gist.github.com/3629539

EDIT

A condition in real code, not shown in the example, checks for the presence of a related object. If the object exists, set the value. If not, ignore the passed value. However, I also use accepts_nested_attributes_for. Thus, an attribute hash may contain attributes for association. In this case, the object will exist.

{:name => 'Fred', :nested_attributes => {:color => 'red'}} 

The name will not be set because the model will not exist.

 {:nested_attributes => {:color => 'red'}, :name => 'Fred'} 

accepts_nested_attributes_for will create a nested instance and then set the attributes. When the name is set, an instance will exist and the nested attribute will be set.

+4
source share
2 answers

Had a similar problem, and I came up with the following reasonably universal 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 highlighted parameter values ​​that you need to set, first you will handle all the weird special cases for assigning attributes (is this a link? A params hash? Multi-value param?). Calling assign_attributes several times with parts of the hash should really have the same effects as calling it with the whole hash once - it should be reasonably safe.

+2
source

The only solution I can think of now is to override the setter attribute ...

 def attributes=(attrs) self[:dont_set_name] = attrs.delete(:dont_set_name) super end 
0
source

Source: https://habr.com/ru/post/1432398/


All Articles