【问题标题】:Rails: callbacks from moduleRails:来自模块的回调
【发布时间】:2023-03-21 21:29:01
【问题描述】:

我尝试这样做:

app/models/my_model.rb:

class MyModel <  ActiveRecord::Base
  include MyModule
  ...
end

lib/my_module.rb:

module MyModule
  before_destroy :my_func    #!

  def my_func
    ...
  end
end

但我得到一个错误:

undefined method `before_destroy' for MyModule:Module

我该如何纠正它。

我也是红宝石的新手。这些“属性”是什么类型:before_destroy、validates、has_many? 它们是变量还是方法还是什么? 谢谢

【问题讨论】:

    标签: ruby-on-rails module mixins


    【解决方案1】:

    before_destroyvalidates 等不是属性或类似的东西。这些是方法调用。

    在 ruby​​ 中,类的主体都是可执行代码,这意味着类主体的每一行都由解释器执行,就像方法主体一样。

    before_destroy :my_func 是一个常用的 ruby​​ 方法调用。被调用的方法是before_destroy,它接收符号:my_func 作为参数。该方法在其被调用范围内的类(或模块)中查找。

    所以继续你的问题,我想你现在应该明白当解释器加载你的模块时

    module MyModule
      before_destroy :my_func    #!
    
      def my_func
        ...
      end
    end
    

    它开始执行它的主体并在这个模块中搜索方法before_destroy,但找不到。您要做的不是在模块上调用此方法,而是在包含模块的类上调用此方法。为此,我们有一个使用Module#included 方法的通用习惯用法:

    module MyModule
      module InstanceMethods
        def my_func
          ...
        end
      end
    
      def self.included(base)
        base.send :include, InstanceMethods
        base.before_destroy :my_func
      end
    end
    

    【讨论】:

      【解决方案2】:

      在 lib/my_module.rb 中,执行以下操作:

      类 MyInheritedClass

      在 app/models/my_model.rb 中,执行以下操作:

      类 MyModel

      您在上面尝试创建的模块中没有 before_destroy 过滤器。我的代码所做的是创建一个将从 ActiveRecord::Base 继承的类,这将是您的所有其他类都可以继承的模板类。模板类还包含 ActiveRecord::Base 的所有属性。

      【讨论】:

        【解决方案3】:

        您可以通过从 MyModule 中删除 before_destroy 并将其放置在 MyModel 中来纠正此问题

        before_destroy 和其他回调仅适用于扩展 ActiveRecord::Base 的类,更多信息here

        希望这会有所帮助 =)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-07
          • 1970-01-01
          • 2019-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多