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_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
于 2011-03-06T11:36:50.503 に答える
0

lib/my_module.rb で、次のようにします。

  class 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 に答える