簡體   English   中英

如何在ActiveRecord事務中獲得保存(無感嘆號)語義?

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

我有兩個模式: PersonAddress ,我想在一個事務中創造出。 也就是說,我想嘗試創建Person ,如果成功,則創建相關的Address 我想使用save語義(返回truefalse )而不是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調用更改為self.saveif self.save塊無效,因為即使Address失敗, Person保存仍然會成功。)

這不起作用,因為它從transaction塊中引發ActiveRecord::StatementInvalid異常而不觸發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文檔特別警告不要在transaction塊中捕獲ActiveRecord::StatementInvalid

我想我的第一個問題是:為什么不是這個交易塊...在兩次保存中進行交易?

這個怎么樣?

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

我不喜歡TX的實現方式。 但這就是你如何解決這些問題。

告訴ActiveRecord為您執行此操作。 為您節省大量問題:

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

好消息是Person的錯誤將包含地址'驗證錯誤,格式正確。

有關更多信息,請參閱AutosaveAssocation模塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM