I have a complex save process (a cyclical reference that needs to be resolved by validating and saving and one model, validating and saving another and then updating the first with an id from the second) that has rollbacks depending on if something bad happened etc.
My models are related in this way:
Accounts have oneSiteContact.Accounts have manyCustomers.SiteContacts are a type ofCustomer.Customers belong to anAccount
Because of the cyclical reference (i.e. Customers are invalid WITHOUT an Account but an Account needs a SiteContact which is a type of Customer.) I decide to save the Account with a blank id for site contact first, then save the site_contact.
I have code similar to this:
# remove the site contact from the account because its not valid yet.
site_contact = params[:account].delete(:site_contact_attributes)
account = Account.new(params[:account])
# some pseudo code
# start database transaction
# validate account
# if valid then
# save account
# site_contact.account_id = account.id
# validate site_contact
# if valid then
# account.site_contact_id = site_contact.id
# save account
# break out!
#
# else
# rollback transaction
# end
# else
# rollback transaction
# end
if Account.exists?(account)
# everything was good! flash[:notice] and redirect somewhere
else
# something bad happened, go back to the page and display the errors.
end
Is it possible to override the Account#save or some other method and move all of that code into my controller? I was looking at before_save and before_create but I’m worried there might be some unintended recursion since I have to save the account twice.
Any ideas?
In your controller:
In your
Accountmodel.The
save!will throw an exception when the validation fails. This will automatically roll back the transaction.