I've two models: Person and Address which Let me create inside a transaction. That's, I wish to attempt to produce the Person and, in the event that works, produce the related Address. I must use save semantics (return true or false) instead of save! semantics (raise an ActiveRecord::StatementInvalid or otherwise).

This does not work since the user.save does not trigger a rollback around 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

(Altering the self.save call for an if self.save block round the relaxation does not help, since the Person save still works even if the Address one fails.)

Which does not work since it boosts the ActiveRecord::StatementInvalid exception from 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 particularly alerts against catching the ActiveRecord::StatementInvalid within the transaction block.

I suppose my first real question is: why is not this transaction block... transacting on saves?

What about this?

class Person
  def save_with_address(address_options = {})
    tx_error = false
    transaction do
      begin
        self.save!
        address = Address.build(address_options)
        address.person = self
        address.save!
      rescue Exception => e
        # add relevant error message to self using errors.add_to_base
        raise ActiveRecord::Rollback 
        tx_error = true 
      end
    end
    return true unless tx_error

    # now roll back the Person TX.
    raise ActiveRecord::Rollback
    return false
  end
end

I do not like how a Texas is implemented. But this is the way you are able to deal with the problems.

Tell ActiveRecord to get this done for you personally. Helps you save mounds of problems:

class Person < ActiveRecord::Base
  belongs_to :address, :autosave => true
end

The excellent factor is the fact that Person's errors will contain address' validation errors, properly formatted.

Begin to see the AutosaveAssocation module to learn more.