我有一个after_create回调模型。此回调会导致在另一个模型中创建新记录。但是,如果创建子记录时验证失败,则原始交易仍在保存中。为什么在回调引用的模型中验证不会导致原始事务失败?
这看起来不对。根据Rails文档,整个事情被包裹在一个事务中。难道我做错了什么?
class ServiceProvision < ActiveRecord::Base
has_one :cash_receipt
after_create :receive_payment_for_service_provision, :if => Proc.new { |sp| sp.immediate_settlement == true }
private
def receive_payment_for_service_provision
cash_account = CashAccount.find_by_currency_id_and_institution_id(self.currency_id, self.institution_id)
CashReceipt.create(:account_id => account.id, :service_provision_id => self.id, :amount => self.amount, :currency_id => self.currency.id, :cash_account_id => (cash_account ? cash_account.id : nil))
end
end
class CashReceipt < ActiveRecord::Base
belongs_to :service_provision
validates_presence_of :cash_account_id
end
的CashReceipt不会失败,但是我的新ServiceProvision对象仍然被保存了被传为cash_account_id零,当返回一个错误。
it "should fail if a cash account doesn't exist for the currency and institution" do
currency = Factory.create(:currency)
institution = Factory.create(:institution)
service_provision = Factory.build(:service_provision, :currency_id => currency.id, :institution_id => institution.id, :immediate_settlement => true)
service_provision.save.should == false
service_provision.should have(1).error
end
'ServiceProvision service provision creation should raise an error if a cash account doesn't exist for the currency and institution' FAILED expected: false,
got: true (using ==)
这似乎从文档
两个基地#保存违背这一点,基料#破坏进来 包裹在确保 ,不管你在验证做或 回调将在发生交易 保护交易的保护。因此,您可以使用验证来检查 值,该交易取决于 ,或者您可以在 回调中引发异常以回滚,包括 after_ *回调。
如果我尝试手动取消交易回调,像这样:
cr = CashReceipt.create(:account_id => account.id, :service_provision_id => self.id, :amount => self.amount, :currency_id => self.currency.id, :cash_account_id => (cash_account ? cash_account.id : nil))
unless cr.errors.empty?
errors.add_to_base("Error while creating CashReciept [#{cr.errors}].")
return false
end
那么新ServiceProvision对象仍保存。
这没有什么区别。虽然错误被提出,但交易仍然完成。哪些飞在面对AR ::交易文档 – Nick 2010-03-01 06:20:50