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我可以使用@some_attribute,因为它将值存储在同名的全局变量中:https ://stackoverflow.com/a/4371458/586000

4

1 回答 1

11

当您在不从另一个类继承的类中使用 attr_accessor 时,根据定义,“父”类中没有同名的方法。因此,super 无处可去寻找同名方法。(好吧,您的类继承自 Object,但 Object 没有定义名为 some_attribute 的方法。)

另一方面,ActiveRecord确实为您的属性定义了一个 getter 和一个 setter。因此,当您在您的类(继承自 ActiveRecord::Base)中再次定义它们时,当您调用 super.

对比 attr_accessor 和 ActiveRecord 为您的表列生成的(许多)方法有点像苹果和橘子的问题。ActiveRecord 对基础表上的属性执行各种操作,包括但不限于为表列创建 getter 和 setter。

(注意上面:ActiveRecord 的工作主要是利用 method_missing 的力量,所以在你的表属性上定义的许多或大部分方法实际上是通过 method_missing 方法实现的。super 实际上会在父类中调用 method_missing,如果它存在的话,因此当您从 ActiveRecord::Base 继承时,您可以成功地在 some_attribute 上调用 super。)

于 2013-01-22T05:50:59.983 回答