我可以从另一个对象的对象上获取一个用于销毁的回调钩子吗?

时间:2015-03-04 14:41:47

标签: ruby-on-rails ruby

Rails 3.1.3 - ruby​​ 1.9.3p194

我有两个对象:患者和法案。

当病人被摧毁时,相应的账单被摧毁。哪个好;但是,这些对象也可以远程保存在Quickbooks上,并通过我的应用程序进行更新。

如果在本地销毁Bill,我的应用程序将删除Quickbooks中的对象。我不会在Quickbooks中销毁患者,因为很可能存储了相关的计费历史记录。

当有人在本地销毁患者时会出现问题,它会调用所有相关法案的销毁,这会触发Quickbooks Bills的销毁方法。

有没有办法看看是否已从比尔模型中调用了patient.destroy?

2 个答案:

答案 0 :(得分:2)

我假设你有类似的东西

class Patient < ActiveRecord::Base
  has_many :bills, dependent: :destroy
end 
class Bills < ActiveRecord::Base
  belongs_to :patient
end

您可以将其更改为

class Patient < ActiveRecord::Base
  has_many :bills, dependent: :delete_all
end 

destroy有一些回调用于从快速手册中删除帐单。

delete没有回调,它只是直接从数据库中删除。

因此,如果您销毁患者,它将在本地删除所有Bills,但不会运行回调以将其从快速手册中删除。

答案 1 :(得分:0)

解决此问题的另一种方法是删除回调并使用单独的协调对象执行删除,该协议对象将从您的控制器调用:

class PatientAndBillRemoteCleanup
  def initialize(patient)
    @patient = patient
  end

  def delete
    Patient.transaction do 
      # fill out these methods
      # transaction rewinds if you have failures
      delete_patients_bills_in_quickbooks
      delete_patients_bills_locally
      delete_patient_locally
    end
  end 
end

这种方法的优点是:

  1. 测试更容易
  2. 您可以将远程删除隔离为已知 过程(因此您不会在Rails控制台上获得意想不到的效果
  3. 使用此代码的任何地方(例如网络控制器) 用户触发删除)很容易理解,和其他人一样 不会在其他地方意外地写出患者删除代码 意外地操纵了快速书
  4. 回调非常适合您希望每隔时间执行某些操作的情况(例如设置一些依赖于其他属性的默认数据),但是您有一种情况,有时您需要回调行为,有时候你不会。将其移出到协调对象,然后您可以轻松控制行为。