У меня есть две модели: Person
и Address
, которые я хотел бы создать в транзакции. То есть я хочу попытаться создать Person
и, если это удастся, создать связанный Address
. Я хотел бы использовать семантику save
(возврат true
или false
), а не семантику save!
(повысить ActiveRecord::StatementInvalid
или нет).
Это не работает, потому что user.save
не вызывает откат транзакции:
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
(Изменение вызова self.save
на блок if self.save
вокруг остальных не помогает, потому что сохранение Person
все еще успешно, даже когда сбой Address
.)
И это не работает, потому что оно вызывает исключение ActiveRecord::StatementInvalid
из блока transaction
без запуска 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
Документация Rails специально предупреждает о перехвате ActiveRecord::StatementInvalid
внутри блока transaction
.
Полагаю, мой первый вопрос: почему этот блок транзакций ... не обрабатывает оба сейва?