0

attribute_fu プラグインに次のコードが表示されます。

module AttributeFu
    module Associations #:nodoc:                                                                                                                                                
        def self.included(base) #:nodoc:                                                                                                                                          
            base.class_eval do
                extend ClassMethods
                class << self; alias_method_chain :has_many, :association_option; end

                class_inheritable_accessor  :managed_association_attributes
                write_inheritable_attribute :managed_association_attributes, []

                after_update :save_managed_associations
            end
        end

        ...
    end
end

交換しようとすると

class << self; alias_method_chain :has_many, :association_option; end

with: alias_method_chain :has_many, :association_option?

次のエラーが表示されます

/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/core_ext/module/aliasing.rb:31:in `alias_method': undefined method `has_many' for class `ActiveRecord::Base' (NameError)
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/core_ext/module/aliasing.rb:31:in `alias_method_chain'
        from /home/twong/git/physpace/vendor/plugins/attribute_fu/lib/attribute_fu/associations.rb:9:in `included'

この 2 行で同じことができると思ったのですが、間違っているようです。誰かが私のエラーを説明できますか?

4

2 に答える 2

3
# init.rb
ActiveRecord::Base.class_eval { include AttributeFu::Associations }

module AttributeFu
    module Associations
        def self.included(base)
            # base == ActiveRecord::Base (the class)
            base.class_eval do
                # class_eval makes self == ActiveRecord::Base, and makes def define instance methods.
                extend ClassMethods

                # If has_many were an instance method, we could do this
                #   alias_method_chain :has_many, :association_option; end
                # but it's a class method, so we have to do the alias_method_chain on
                # the meta-class for ActiveRecord::Base, which is what class << self does.
                class << self; alias_method_chain :has_many, :association_option; end
            end
        end
    end
end

これをいじる別の方法は、これを IRB に入れることです。

class A ; end
A.class_eval { puts self.inspect ; class << self ; puts self.inspect ; end }

こちらもご覧ください

于 2008-12-05T19:27:03.127 に答える
0

その場合、selfanObject を意味するのではなく、むしろ砂糖構造です。

class << self
  ...
end

囲んでいるオブジェクトのクラス メソッドを定義します。メソッドalias_method_chainはメソッドであり、別名を付けます。その場合、それは と にエイリアスさhas_manyhas_many_without_association_optionsます。あなたの場合、クラスメソッドのエイリアスであるため、クラスメソッドスコープで使用する必要があります。手間をかけずにメソッドを拡張できます。has_many_with_association_optionshas_many

クラスメソッドは次のように呼び出されます。

SomeThing.bar_method

一方、インスタンス メソッドは class のインスタンスで呼び出されます。

assoc = SomeThing.new
assoc.foo_method

対応するコードは次のとおりです。

class SomeThing
  def foo_method
    ...
  end
  class << self
    def bar_method
      ...
    end
  end
end

あなたの場合、モジュールがありますAttributeFu::Associations。クラス Foo に含まれている場合、Foo 内でいくつかのインスタンス属性を定義する Foo.class_eval を実行しalias_method_chain、クラス メソッド スコープ ( class << self) 内でメソッドを起動します。

extends ClassMethods次のいずれかを定義する必要がある もあります。

def self.has_many_with_association_options
    ...
end

また

class << self
  def has_many_with_association_options
    ...
  end
end
于 2008-12-04T22:34:22.283 に答える