我有一个观察者设置如下:
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 ..
在观察者中,我如何确定调用导致观察者被调用的方法?
由于
答案 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
不依赖于花哨的元编程(比如检查调用堆栈),可以使程序更具弹性,也更容易理解。这同样适用于回调,甚至更多的外部观察者类。在原始模型中,通常只有很少的回调存在的痕迹(如果有的话)。这使得分析行为非常复杂且容易出错,因为您可以轻松忽略业务逻辑中潜在的重要部分。通过实现直接功能,您可以使逻辑更容易理解,因为它遵循一条简单的直线。
如果有疑问,总是最可能有效的最愚蠢和最简单的事情。调试代码通常需要两倍才能编写代码。所以做一些聪明的事情可能会导致以后有效的无法维护的代码,因为人们只是不够聪明,无法理解你的逻辑流程。