Rails Observer,如何确定触发after_destroy的内容

时间:2011-02-14 04:32:06

标签: ruby-on-rails ruby-on-rails-3

我有一个观察者设置如下:

class FeedObserver < ActiveRecord::Observer
  observe :permission
  def after_destroy(record)

    Rails.logger.info 'XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX'
    Rails.logger.info record.inspect
    Rails.logger.info record.class.name
    Rails.logger.info record.class
    Rails.logger.info 'XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX'

  end

end

在日志中,这看起来有点像:

XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX
#<Permission id: 52, project_id: 12, role_id: 2, user_id: 1>
Permission
Permission
XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX

这个问题是在我的权限控制器中有两种方法可以删除权限对象,destory和leaveproject ..

在观察者中,我如何确定调用导致观察者被调用的方法?

由于

3 个答案:

答案 0 :(得分:0)

嗯,你不知道,但我不应该很难找到。

它在销毁之后,如果你遵循约定,它应该在 feeds_controller.rb FeedsController#destroy ,或者在 :dependent => :destroy 关联的情况下,它应该在关联控制器中摧毁行动。

另一个简单的方法是使用ruby raise 方法引发一个虚假错误,并让自己走过堆栈跟踪

答案 1 :(得分:0)

尝试使用内核#caller,它将在执行堆栈中的那一点返回回溯。试试这样:

def after_destroy(record)
  Rails.logger.info caller.join("\n")
  ...

你会得到一些输出,但如果你跳过rails框架的东西,你应该找到你的控制器代码。

答案 2 :(得分:0)

如果这对你来说非常重要,一个更简单的解决方案可能是在模型类上创建自己的方法来调用destroy并直接执行任何清理工作。然后,此功能可以接收有关呼叫者的其他信息。这样的事情可以奏效:

class Work < ActiveRecord::Base
  def destroy_work(from)
    self.destroy
    Rails.logger.info "The work with the id of #{id} got destroyed by #{from}"
  end
end

不依赖于花哨的元编程(比如检查调用堆栈),可以使程序更具弹性,也更容易理解。这同样适用于回调,甚至更多的外部观察者类。在原始模型中,通常只有很少的回调存在的痕迹(如果有的话)。这使得分析行为非常复杂且容易出错,因为您可以轻松忽略业务逻辑中潜在的重要部分。通过实现直接功能,您可以使逻辑更容易理解,因为它遵循一条简单的直线。

如果有疑问,总是最可能有效的最愚蠢和最简单的事情。调试代码通常需要两倍才能编写代码。所以做一些聪明的事情可能会导致以后有效的无法维护的代码,因为人们只是不够聪明,无法理解你的逻辑流程。