【发布时间】:2014-11-14 04:00:38
【问题描述】:
我有以下课程:
class AwardBase
class AwardOne < AwardBase
class Post < ActiveRecord::Base
Post 是 ActiveRecord,Award 有 can_award 吗?类方法,它接受一个 post 对象并检查它是否符合某些条件。如果是,它会更新 post.owner.awards。
我知道我可以使用观察者模式来做到这一点(我对其进行了测试并且代码运行良好)。但是,这需要我向模型添加额外的代码。如果可能的话,我根本不想碰这个模型。我想做的是像这样运行 Award 检查(触发器将在类加载时调用):
class AwardOne < AwardBase
trigger :post, :after_save
def self.can_award?(post)
...
end
end
上面代码的意图是自动添加AwardOne.can_award?到 Post 的 after_save 方法
所以基本上我要做的是让trigger 调用相当于:
class Post < ActiveRecord::Base
after_save AwardOne.can_award?(self)
...
end
基本上是:
class Post < ActiveRecord::Base
after_save :check_award
def check_award
AwardOne.can_award?(self)
end
end
如何在不修改 Post 类的情况下做到这一点?
这是我所做的(似乎不起作用):
class AwardBase
def self.trigger (klass, active_record_event)
model_class = klass.to_class
this = self
model_class.instance_eval do
def award_callback
this.can_award?(self)
end
end
model_class.class_eval do
self.send(active_record_event, :award_callback)
end
end
def self.can_award? (model)
raise NotImplementedError
end
end
上面的代码失败并出现错误:
NameError (undefined local variable or method `award_callback' for #<Post:0x002b57c04d52e0>):
【问题讨论】:
-
请提供此错误的堆栈跟踪。
-
您可以使用 ActiveSupport::Concerns,类似于此处接受的答案:stackoverflow.com/questions/12084234/…
-
但您仍然必须将其包含在您的模型中!!不过我不太确定
-
我怀疑这条线
model_class = klass.to_class是否真的有效。 Symbol 中没有to_class方法可以将其更改为类。你确定它是否有效? -
@User089247 我已经给符号添加了猴子补丁到_class。它只是做一个 to_s.classify.constantize
标签: ruby-on-rails ruby metaprogramming