Michael Schuerig
2006-Dec-23 21:59 UTC
Creating/updating multiple associated objects at the same time
The problem: For me it''s a common case that I want to create or update multiple associated objects at the same time from a single params hash. The restrictions: This is clearly functionality that belongs in the model. The operation obviously has to be transactional, either all objects are created/updated or none. A solution. Well, it works for me. def initialize(attributes = nil) # initialize already executes inside a transaction # there''s no point in adding a further transaction block base_attributes, child_attributes split_attributes(attributes) super(base_attributes) attach_children(child_attributes) end # Use this instead of update_attributes in controller. def update_properties!(attributes) base_attributes, child_attributes split_attributes(attributes) self.class.transaction do attach_children(child_attributes) update_attributes(base_attributes) || raise(ActiveRecord::RecordInvalid, self) end end def split_attributes(attributes) ... end def attach_children(attributes) # find, create, or update the children based on given attributes # raises an exception if anything goes wrong end As I said, this works for me, but it doesn''t feel nice and clean. I have to override initialize, which I''d rather not do and leave this method entirely to ActiveRecord. Similar for updating. Overriding update_attributes suitably doesn''t seem feasible[*], and I wouldn''t want to anyway. [*] If anything goes wrong, the surrounding transaction has to be aborted to cause a rollback. This can only be done *reliably* by raising an exception from update_properties! as the method might be executing in an outer transaction block in which case an exception has to be raised out of that transaction block to actually abort the transaction. As I''m pretty sure that I''m not the only one whose trying to tackle this problem, I''m really interested in other approaches. Michael -- Michael Schuerig mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org http://www.schuerig.de/michael/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---