Rails如何仅为一个自定义方法添加观察者
Rails如何仅为一个自定义方法添加观察者
我想创建一个观察者,只观察一个自定义方法。\n我有一个Banner模型。对于每次调用`image`方法,我想要增加`pageview`字段的值。\n
class Banner < ActiveRecord::Base has_attached_file :image def pageview_inc self.pageview += 1 save end alias old_image image def image old_image end end
\n是否可能为只有一个自定义方法设置观察者?\n在调用`image`方法后,执行`pageview_inc`方法。\n编辑\n如果我将该方法更改为\n
def image old_image self.pageview += 1 self.save! end
\n我会得到`stack level too deep`的错误。\n对于以下代码也会产生同样的效果:\n
def image self.pageview += 1 self.save! old_image end
问题出现的原因:需要给一个自定义方法添加观察者,但是不知道如何实现。
问题的解决方法:可以按照以下步骤进行解决。
1. 首先,创建一个自定义方法,比如"image"。
def image old_image write_attribute("pageview", pageview + 1) end
2. 在该方法中,先调用原始的方法,比如"old_image",以确保原始的功能不受影响。
3. 然后,使用"write_attribute"方法来更新相应的属性。在这个例子中,我们将"pageview"属性的值增加1。
通过以上步骤,我们可以将观察者添加到自定义方法中,并且保持原始的功能不变。
在上述代码中,Baner类继承自ActiveRecord::Base,其中定义了一个image方法。在image方法中,调用了increment!方法对pageview属性进行递增操作,并且调用了old_image方法。
问题的出现原因是,在image方法中调用了old_image方法,但是old_image方法并没有被定义。因此,我们需要添加一个观察者来监听image方法的调用,并且在调用之前先检查old_image方法是否存在。
解决方法是使用Rails的Observer模式。可以创建一个名为BanerObserver的观察者类,然后在Baner类中通过调用observe :baner
来指定要观察的类。在观察者类中,可以定义before_update回调方法,在其中检查old_image方法是否存在。
下面是解决问题的代码示例:
class BanerObserver < ActiveRecord::Observer def before_update(baner) if baner.respond_to?(:old_image) # do something end end end class Baner < ActiveRecord::Base has_attached_file :image alias_method :old_image, :image def image increment!(:pageview) old_image end end BanerObserver.instance.observe :baner