How do I get save (no exclamation point) semantics in an ActiveRecord transaction?

Posted by James A. Rosen on Stack Overflow See other posts from Stack Overflow or by James A. Rosen
Published on 2010-03-20T03:36:14Z Indexed on 2010/03/20 3:41 UTC
Read the original article Hit count: 293

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?

© Stack Overflow or respective owner

Related posts about ruby-on-rails

Related posts about activerecord