【问题标题】:Alias method chain with method not defined方法未定义的别名方法链
【发布时间】:2012-10-12 01:27:14
【问题描述】:

我有一个包含在 Rails Observer 中的模块。

目的是:

  • 调用after_saveafter_update 一个名为check_integrity 的方法
  • 如果在 Observer 中定义,请在 after_save 或/和 after_update 末尾调用 check_integrity

简而言之,它应该始终调用check_integrity

我尝试了如下代码:

module IntegrityObserver
  extend ActiveSupport::Concern

  included do
    alias_method_chain :after_save,   :check_integrity
    alias_method_chain :after_update, :check_integrity
  end

  def check_integrity
    # do something
  end
end

class UserObserver < ActiveRecord::Observer
  include IntegrityObserver

  def after_save(object)
    # do something
  end
end

但它会引发错误:activesupport-3.0.17/lib/active_support/core_ext/module/aliasing.rb:31:in alias_method': undefined method after_update' for class TaskObserver' (NameError)

有人知道我怎样才能做我想做的事吗?

谢谢!

【问题讨论】:

  • include CacheObserver 行是否打算成为include IntegrityObserver? TaskObserver 是从哪里来的?在after_save 定义之后包含模块 是否有帮助?
  • 谢谢我修复了它@x1a4,包括 after_save 之后会起作用,但在方法未定义时不起作用

标签: ruby-on-rails ruby metaprogramming alias-method-chain


【解决方案1】:

ActiveRecord 已经提供了观察者功能来监控模型的生命周期。以下是如何注册一个响应多个模型的通用观察者:

class AuditObserver < ActiveRecord::Observer
  observe :account, :balance

  def after_update(record)
    AuditTrail.new(record, "UPDATED")
  end
end

在您的 config/application.rb 文件中:

config.active_record.observers = :audit_observer

查看更多示例here

【讨论】:

    【解决方案2】:

    alias_method_chain 不是这样工作的。如果您定义类似:

    alias_method_chain :after_save,   :check_integrity
    

    您必须定义以下方法:

    def after_save_with_check_integrity(*args)
      # do something
      # you can call the original after_save by calling:
      # after_save_without_check_integrity(*args)
    end
    

    请注意,在大多数情况下使用 alias_method_chain 被认为是一种不好的做法。

    【讨论】:

      【解决方案3】:

      与模型不同,观察者没有预定义的回调方法,例如 after_save、after_update。所以你得到了一个“未定义的方法”错误。

      你可以这样做,

      module IntegrityObserver
        extend ActiveSupport::Concern
      
        def after_save(record)
          check_integrity
        end
      
        def after_update(record)
          check_integrity
        end
      
        def check_integrity
          # do something
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        • 1970-01-01
        • 2012-07-01
        • 2012-11-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多