【问题标题】:custom callbacks with observer in rails3rails3 中带有观察者的自定义回调
【发布时间】:2011-07-01 05:18:19
【问题描述】:

我对一个问题感到绝望。

我想注册自定义回调:after_something 然后将该回调用于观察者。

我曾尝试使用 define_callbacks、set_callbacks 但观察者从未触发该回调。

我知道我可以使用 AR 回调,但我只是更喜欢在某些情况下使用我自己的回调。

谢谢

【问题讨论】:

    标签: ruby-on-rails callback observer-pattern


    【解决方案1】:

    Observer 使用标准 AR 回调,因此它不会触发您的默认回调。

    我认为不如发明新的回调(以及 AR 的猴子补丁默认行为),也许您应该使用 AR。很难说你想要什么。能给个用例吗?

    试试看

    before_save MyCallbacks.new, :if => :some_condiditons_meet?
    
    class MyCallbacks
      def before_save(object)
        sophistcated_use(object) if object.valid?
        damn_have_it?
      end
    end
    

    它实际上在某种程度上涵盖了观察者的行为

    保存、保存!或销毁调用的整个回调链在事务中运行。这包括 after_* 钩子。如果一切顺利,则在链完成后执行 COMMIT。

    我认为单一观察者的整个想法并不是最好的解决方案。在更多依赖项到达后,您的逻辑将非常复杂。定义自己的事务包装器很好,但你真的需要它吗?也许您可以重新安排模型来实现它,而无需编写自己的交易案例。

    例如

    class Friendship < ActiveRecord::Base
      belongs_to :user
      has_many :users, :through => :groups
    
      after_validation :save_my_records
    
      def save_my_records
        user.friend.history.save
        user.history.save
      end
    
    end
    

    朋友是对象 => 有自己的观察者 历史是对象 => 有自己的观察者

    它非常抽象,但是如果没有你的代码,我不知道如何给出一些建设性的例子,而且 after_validation 也不是保存我认为的任何东西的最佳位置。

    notify_observer 对我来说听起来也像 hack :-)

    【讨论】:

    • 感谢您的回答。我有类似友谊模型的东西,我必须在验证后保存两条记录。为此我使用事务。我的电子邮件观察者变得复杂,因为我想使用一个观察者来处理所有电子邮件通知。因为我必须检查的是记录一些东西,然后触发消息通知......在这种情况下,我认为自定义回调可能是有用的东西......
    • @vule 添加一些与基本模型关联的其他模型并启动保存将使用事务 ootb 包装所有内容。验证后保存两条记录而不保存基本模型(从应该触发的位置)对我来说听起来不安全。我为一些例子编辑了我的答案。
    【解决方案2】:

    如果有人在寻找以下解决方案:

    在你的模型中调用这个:

    notify_observers(:after_my_custom_callback)
    

    在你的观察者中定义方法:

    def after_my_custom_callback(record)
    
     #do things
    end
    

    【讨论】:

    • 谢谢。我正在从 Rails 2.3 升级到 3.0,我只需要将 notify 更改为 notify_observers
    【解决方案3】:

    感谢 Alex 的回答,我可以通过定义应调用的 define_model_callbacks_for_observers 方法而不是 define_model_callbacks 来解决此问题(您可能希望将其放入模块中):

    def define_model_callbacks_for_observers(*args)
      types = Array.wrap(args.extract_options![:only] || [:before, :around, :after])
    
      callbacks = define_model_callbacks(*args)
    
      callbacks.each do |callback|
        types.each do |filter|
          set_callback(callback, filter) do
            notify_observers :"#{filter}_#{callback}"
            true
          end
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-08-26
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      相关资源
      最近更新 更多