How do I get save (no exclamation point) semantics in an ActiveRecord transaction?
- by James A. Rosen
I have two models: Person and Address which I'd like to create in a transaction. That is, I want to try to create the Person and, if that succeeds, create the related Address. I would like to use save semantics (return true or false) rather than save! semantics (raise an ActiveRecord::StatementInvalid or not).
This doesn't work because the user.save doesn't trigger a rollback on the transaction:
class Person
def save_with_address(address_options = {})
transaction do
self.save
address = Address.build(address_options)
address.person = self
address.save
end
end
end
(Changing the self.save call to an if self.save block around the rest doesn't help, because the Person save still succeeds even when the Address one fails.)
And this doesn't work because it raises the ActiveRecord::StatementInvalid exception out of the transaction block without triggering an ActiveRecord::Rollback:
class Person
def save_with_address(address_options = {})
transaction do
save!
address = Address.build(address_options)
address.person = self
address.save!
end
end
end
The Rails documentation specifically warns against catching the ActiveRecord::StatementInvalid inside the transaction block.
I guess my first question is: why isn't this transaction block... transacting on both saves?