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
答案 0 :(得分:11)
当您在类中使用不继承自另一个类的attr_accessor时,根据定义,“父”类中没有相同名称的方法。因此,super无处可寻找同名的方法。 (好吧,你的类继承自Object,但是Object没有定义名为some_attribute的方法。)
另一方面,ActiveRecord 为您的属性定义一个getter和一个setter。因此,当你在你的类(继承自ActiveRecord :: Base)中再次定义它们时,当你调用super时,Ruby有一个地方可去(ActiveRecord :: Base)
对比attr_accessor和ActiveRecord为你的表列生成的(很多)方法,有点像苹果和橘子的问题。 ActiveRecord使用基础表上的属性执行各种操作,包括 - 但不限于 - 为表列创建getter和setter。
(注意以上内容:ActiveRecord主要通过利用method_missing的强大功能,因此在表属性上定义的许多或大多数方法实际上是通过method_missing方法实现的。事实上,super确实调用了method_missing,如果存在的话,在父类中,这样就可以在从ActiveRecord :: Base继承时成功调用some_attribute上的super。)