views:

412

answers:

1

Is there a better way of writing this code? It just doesn't sit right with me, I feel like there is something really 'rails like' that I should already know:

belongs_to :parent_in_use
belongs_to :parent_template

def after_create
  new_parent_in_use = ParentInUse.create!(self.parent_template.attributes)
  self.update_attribute(:parent_in_use_id, new_parent_in_use.id)
end

After creating a record I am taking the selected parent template and creating a parent_in_use record based on it. This way the template can change and the in_use record will live with my object forever. Both the ParentInUse and ParentTemplate classes inherit from Parent using STI.

I'm sure this should be simple enough but I don't know how to do it, basically I would like to create the and assign the record in one operation.

A: 

This will do what you're looking for.

def after_create 
  self.parent_in_use = ParentInUse.create!(parent_template.attributes)
end

However without other changes it won't do you any good. Because the foreign key is stored in the current model, ActiveRecord won't save the change if this association is created by an after_create call back. The new ParentInUse object will be saved, but the database row for the current model will not be updated with that corresponding parent_in_use_id.

Call it as a before_create call back and things will go more smoothly.

EmFi
I was wanted to be 100% confident that the current_model existed before creating the corresponding record. If the model is not valid I assume it will not get to the before_create callback?
tsdbrown
That's a valid assumption. Also all callbacks are wrapped in the a single transaction, if any of them returns false or raises an error, the entire transaction is rolled back. So the ParentInUse will not be created unless everything along the way succeeds.
EmFi