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?