The other day I received an email about the post concerning multi-model forms in Rails. This person had a similar situation, but was having difficulty saving the records on an update. I didn’t make that part very clear, so I figured I’d complete the puzzle.
If you recall, there was a check in the set_model_attributes method that looks for an id (attributes[:id].blank?) so it’d know whether it was supposed to update or create. If there’s an id present, it must be an update.
Based on these two lines,
_model = send(model).detect {|m| m.id == attributes[:id].to_i} _model.attributes = attributes
there’s a misconception that the model’s attributes are getting saved. Setting the attributes like this does not save them, but it’s easy to do. I’m using an after_update callback which looks like this:
class Course < ActiveRecord::Base has_many :holes, :dependent => :destroy has_many :tees, :dependent => :destroy after_update { |c| c.save_associated :holes, :tees } # ... end
And the save_associated method looks like this:
def save_associated(*models) models.each do |model| send(model).each do |attributes| # handle validations before this point # and pass false to the save method to # ensure that the attributes get saved attributes.save(false) end end end
If you’re only dealing with one association you can eliminate the parameters and the nested loop, as well as provide a more meaningful method name for the callback (such as save_holes). All in all, this seems to work pretty good.
Chris mentioned conductors in an earlier comment, which also seems like a viable option.





