与attr_accessor相比,ActiveRecord如何定义方法?

时间:2022-09-11 17:36:27

ActiveRecord seems to define instance methods differently than attr_accessor.

ActiveRecord似乎以不同于attr_accessor的方式定义实例方法。

attr_accessor doesn't seem to define a super method for my new defined attribute:

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..

Whereas ActiveRecord definitely defines a super method:

而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

Where is the difference between both? Is there a way to make attr_accessor define a super method?

两者之间的区别在哪里?有没有办法让attr_accessor定义一个超级方法?

EDIT: I still don't know how ActiveRecord defines it's methods, but I know how attr_accessor does it. Instead of super I can use @some_attribute since it stores the values in global variables of the same name: https://*.com/a/4371458/586000

编辑:我仍然不知道ActiveRecord如何定义它的方法,但我知道attr_accessor是如何做到的。而不是超级我可以使用@some_attribute,因为它将值存储在同名的全局变量中:https://*.com/a/4371458/586000

1 个解决方案

#1


11  

When you use attr_accessor in your class that does not inherit from another class, there is, by definition, no method by the same name in a "parent" class. Therefore, super has nowhere to go to find a same-named method. (Well, your class inherits from Object, but Object does not define a method named some_attribute.)

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

On the other hand, ActiveRecord does define a getter and a setter for your attributes. Therefore, when you define them again in your class (that inherits from ActiveRecord::Base), then Ruby has somewhere to go (ActiveRecord::Base) when you invoke super.

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

Contrasting attr_accessor and the (many) methods that ActiveRecord generates for your table columns is a bit of an apples and oranges kind of question. ActiveRecord does all sorts of things with the attributes on the underlying table, including--but not limited to--creating getters and setters for the table columns.

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

(Note on the above: ActiveRecord works mostly by harnessing the power of method_missing, so many or most of the methods defined on your table attributes are actually implemented through the method_missing method. super does in fact invoke method_missing, if it exists, in parent classes, so that is how you can successfully invoke super on some_attribute when you inherit from ActiveRecord::Base.)

(注意以上内容:ActiveRecord主要通过利用method_missing的强大功能,因此在表属性上定义的许多或大多数方法实际上是通过method_missing方法实现的。事实上,super实际上调用了method_missing,如果它存在,则在父类中,这就是当您从ActiveRecord :: Base继承时,如何在some_attribute上成功调用super。)

#1


11  

When you use attr_accessor in your class that does not inherit from another class, there is, by definition, no method by the same name in a "parent" class. Therefore, super has nowhere to go to find a same-named method. (Well, your class inherits from Object, but Object does not define a method named some_attribute.)

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

On the other hand, ActiveRecord does define a getter and a setter for your attributes. Therefore, when you define them again in your class (that inherits from ActiveRecord::Base), then Ruby has somewhere to go (ActiveRecord::Base) when you invoke super.

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

Contrasting attr_accessor and the (many) methods that ActiveRecord generates for your table columns is a bit of an apples and oranges kind of question. ActiveRecord does all sorts of things with the attributes on the underlying table, including--but not limited to--creating getters and setters for the table columns.

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

(Note on the above: ActiveRecord works mostly by harnessing the power of method_missing, so many or most of the methods defined on your table attributes are actually implemented through the method_missing method. super does in fact invoke method_missing, if it exists, in parent classes, so that is how you can successfully invoke super on some_attribute when you inherit from ActiveRecord::Base.)

(注意以上内容:ActiveRecord主要通过利用method_missing的强大功能,因此在表属性上定义的许多或大多数方法实际上是通过method_missing方法实现的。事实上,super实际上调用了method_missing,如果它存在,则在父类中,这就是当您从ActiveRecord :: Base继承时,如何在some_attribute上成功调用super。)