Pregunta ¿Cómo define ActiveRecord los métodos en comparación con attr_accessor?


ActiveRecord parece definir los métodos de instancia de forma diferente a attr_accessor.

attr_accessor no parece definir un supermétodo para mi nuevo atributo definido:

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

Mientras ActiveRecord definitivamente define un super método:

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

¿Dónde está la diferencia entre ambos? ¿Hay alguna manera de hacer attr_accessor definir un supermétodo?

EDITAR: Todavía no sé cómo ActiveRecord define sus métodos, pero sé cómo attr_accessor lo hace. En lugar de super Puedo usar @some_attribute ya que almacena los valores en variables globales del mismo nombre: https://stackoverflow.com/a/4371458/586000


6
2018-01-18 15:09


origen


Respuestas:


Cuando utiliza attr_accessor en su clase que no hereda de otra clase, no hay, por definición, ningún método con el mismo nombre en una clase "principal". Por lo tanto, super no tiene a dónde ir para encontrar un método del mismo nombre. (Bueno, su clase hereda de Object, pero Object no define un método llamado some_attribute).

Por otro lado, ActiveRecord hace define un getter y un setter para tus atributos. Por lo tanto, cuando  definirlos de nuevo en tu clase (que hereda de ActiveRecord :: Base), luego Ruby tiene que ir a algún lugar (ActiveRecord :: Base) cuando invocas super.

El contraste de attr_accessor y los (muchos) métodos que ActiveRecord genera para las columnas de su tabla es una especie de pregunta de manzanas y naranjas. ActiveRecord hace todo tipo de cosas con los atributos en la tabla subyacente, incluyendo, pero no limitado a, la creación de captadores y definidores para las columnas de la tabla.

(Nota sobre lo anterior: ActiveRecord funciona principalmente al aprovechar el poder de method_missing, por lo que muchos o la mayoría de los métodos definidos en los atributos de su tabla se implementan a través del método method_missing. Super, de hecho, invoca method_missing, si existe, en las clases primarias , así es como puedes invocar con éxito super en some_attribute cuando heredas de ActiveRecord :: Base.)


11
2018-01-22 05:50



Preguntas populares