6

我尝试这样做:

应用程序/模型/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?它们是变量还是方法还是什么?谢谢

4

3 回答 3

16

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

在 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
于 2011-03-06T11:36:50.503 回答
0

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

  类 MyInheritedClass < ActiveRecord::Base
    before_destroy :my_func
    def my_func
       ...
    结尾
  结尾

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

类 MyModel < MyInheritedClass
  ...
结尾

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

于 2011-03-06T11:09:09.890 回答
0

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

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

希望这会有所帮助=)

于 2011-03-06T11:11:19.050 回答