0

我有以下模型:

class PhoneNumber < ActiveRecord::Base
  has_many :personal_phone_numbers, :dependent => :destroy
  has_many :people, :through => :personal_phone_numbers
end

我想设置一个观察者在延迟作业队列中运行一个动作,该队列在大多数情况下都有效,但有一个例外。我希望 before_destroy 观察者在电话号码被销毁之前抓住与电话号码相关的人,而延迟的工作实际上是在这些人身上起作用。

问题是,当一个电话号码被销毁时,它会:personal_phone_numbers先销毁记录,然后在它试图销毁电话号码时触发观察者。到那时,为时已晚。

在删除依赖记录之前,有什么方法可以观察销毁操作?

4

5 回答 5

0

您可以在模型中使用 before_destroy 回调,然后在销毁父对象之前获取数据并执行您需要的任何操作。像这个例子这样的东西应该是你正在寻找的:

class Example < ActiveRecord::Base
before_destroy :execute_random_method


private

def execute_random_method
  ...
end
handle_asynchronously :execute_random_method
于 2012-08-07T23:04:04.277 回答
0

使用alias_method 拦截destroy 调用?

class PhoneNumber < ActiveRecord::Base
  has_many :personal_phone_numbers, :dependent => :destroy
  has_many :people, :through => :personal_phone_numbers

  alias_method :old_destroy, :destroy

  def destroy(*args)
    *do your stuff here*
    old_destroy(*args)
  end
end
于 2012-08-06T22:44:33.507 回答
0

简而言之,听起来您的问题是您想要收集PersonaPersonalPhoneNumber被销毁时的集合并对其采取行动。这种方法可能符合要求!

Person这是收集模型的自定义回调示例。这里它是一个实例方法,因此我们不必PersonalPhoneNumberCallbacks在 ActiveRecord 模型中实例化对象。

class PersonalPhoneNumberCallbacks
  def self.after_destroy(personal_phone_number)
    # Something like people = Person.find_by_personal_phone_number(personal_phone_number)
    # Delayed Job Stuff on people
  end
end

接下来,为您的 ActiveRecord 模型添加回调:

class PersonalPhoneNumber < ActiveRecord::Base
  after_destroy PictureFileCallbacks
end

您的after_destroy回调将传递模型,您可以对其数据采取行动。回调链完成后,将被销毁。

参考

于 2012-08-07T22:04:32.470 回答
0

虽然这并不理想,但您可以:dependent => :destroypersonal_phone_numbers关系中删除 ,并在对它们进行操作后在观察者中手动删除它们。

但是,我认为这个问题可能会向您展示代码异味。你为什么要在电话号码的观察者中对人进行操作。听起来这个逻辑在连接模型中处理得更好。

于 2012-08-06T22:32:39.863 回答
0

有点老了,但我想我会分享一下 rails 现在为 before_destroy 回调提供了不错的“前置”选项。这遵循与tomciopp相同的思路,但允许您在类中的任何位置定义 before_destroy。

before_destroy :find_associated_people, prepend: true

def find_associated_people
  # using phone number, find people
end
于 2021-09-14T18:48:48.467 回答