6

ActiveRecord は attr_accessor とは異なる方法でインスタンス メソッドを定義しているようです。

attr_accessor は、新しく定義した属性のスーパー メソッドを定義していないようです。

class SomeClass
  attr_accessor :some_attribute

  def some_attribute
    super
  end
end

>> some_class = SomeClass.new
>> some_class.some_attribute
NoMethodError: super: no superclass method `some_attribute' for..

一方、ActiveRecord は確実にスーパー メソッドを定義します

class SomeClass < ActiveRecord::Base
  # some_attribute is now a column in our database

  def some_attribute
    super
  end
end

>> some_class = SomeClass.new
>> some_class.some_attribute
nil

両方の違いはどこにありますか?attr_accessor にスーパーメソッドを定義させる方法はありますか?

編集: ActiveRecord がそのメソッドを定義する方法はまだわかりませんが、attr_accessor がそれを行う方法は知っています。同じ名前のグローバル変数に値を格納するので、代わりにsuper使用できます: https://stackoverflow.com/a/4371458/586000@some_attribute

4

1 に答える 1

11

別のクラスから継承しないクラスで attr_accessor を使用する場合、定義により、「親」クラスに同じ名前のメソッドはありません。したがって、スーパーには同じ名前のメソッドを見つける場所がありません。(まあ、あなたのクラスは Object を継承していますが、Object は some_attribute という名前のメソッドを定義していません。)

一方、ActiveRecord、属性のゲッターとセッターを定義します。したがって、クラス(ActiveRecord::Base から継承)でそれらを再度定義すると、 super を呼び出したときに Ruby に移動先 (ActiveRecord::Base) ができます。

attr_accessor と ActiveRecord がテーブルの列に対して生成する (多くの) メソッドを比較することは、リンゴとオレンジのような質問です。ActiveRecord は、基礎となるテーブルの属性を使用してあらゆる種類のことを行います。これには、テーブル列のゲッターとセッターの作成が含まれますが、これに限定されません。

(上記の注意: ActiveRecord は主に method_missing の力を利用することによって機能するため、テーブル属性で定義されたメソッドの多くまたはほとんどは、実際には method_missing メソッドを介して実装されます。実際、親クラスに存在する場合、スーパーは method_missing を呼び出します。 、したがって、ActiveRecord::Base から継承するときに some_attribute で super を正常に呼び出す方法です。)

于 2013-01-22T05:50:59.983 に答える