ruby on rails - rails - Llamadas al método Ruby declaradas en el cuerpo de la clase
ruby on rails tutorial (5)
El cuerpo de una definición de clase es un contexto de ejecución para el código como cualquier otro. El código se ejecuta dentro del contexto de la clase (es decir, self
es el objeto de clase, que es una instancia de Class). Puede tener locales y variables de instancia (que pertenecerán al objeto de clase en sí en lugar de instancias de la clase) y puede llamar a cualquier método al que responda el objeto de clase. El código se ejecuta una vez que el bloque de definición de clase finaliza.
En este caso, ActiveRecord :: Base define los métodos de clase validates_presence_of
y belongs_to
.
Acabo de empezar a aprender Ruby on Rails y me he encontrado con el código siguiente:
class Post < ActiveRecord::Base
validates_presence_of :title
belongs_to :user
end
Hay dos llamadas al método dentro del cuerpo de la clase. Me ha costado encontrar cualquier documentación de Ruby que describa cómo funcionan las llamadas de método desde un cuerpo de una clase (pero fuera de cualquier método). Todos los libros que tengo solo describen cómo definir los métodos de clase e instancia y cómo llamarlos desde otros métodos.
Las preguntas que tengo son: ¿cómo y cuándo se llaman estos métodos? ¿Cómo se definen? ¿Están mixins definidos en algún módulo de registro activo?
Estos son métodos de clase o métodos ''singleton''. Uno con el que debe estar familiarizado es attr_accessor. Podemos implementar algo así en una clase de prueba.
class Klass
def self.add_getter_and_setter(symbol)
module_eval "def #{symbol}; @#{symbol}; end"
module_eval "def #{symbol}=(val); @#{symbol} = val; end"
end
end
class Person < Klass
add_getter_and_setter :name
add_getter_and_setter :phone
end
person = Person.new
person.name = ''John Smith''
person.phone = ''555-2344''
person # returns <Person:0x28744 @name="John Smith", @phone="555-2344">
En el ejemplo anterior, creamos el método de clase con ''def self.add_getter_and_setter'' pero esta no es la única manera.
class Klass
class << self # opens the singleton class
def add_getter_and_setter(symbol) # note we dont specify self as it is already within the context of the singleton class
..
end
end
end
Usando extender. Module # extends es un método que amplía una clase con métodos de clase, así como el método Module #include incluye una clase con métodos de instancia.
class Klass
extend(Module.new do
def add_getter_and_setter(symbol)
..
end
end)
end
Si Klass ya se ha definido, podemos volver a abrirlo para agregar métodos de clase
class Klass
end
def Klass.add_getter_and_setter(symbol)
..
end
# or
class << Klass
def add_getter_and_setter(symbol)
..
end
end
Bueno, esas son algunas de las formas en que sé cómo hacerlo, así que si ves una sintaxis diferente, simplemente te das cuenta de que todo está haciendo lo mismo.
Nota: en los rieles, un método de clase común que todos usamos es ''encontrar''. Se ejecuta directamente fuera de la clase Modelo.
person = Person.find(1) # finds a person with id:1
Lo que está viendo son métodos de nivel de clase para un objeto ActiveRecord. Para escribir sus propios métodos que funcionan de esta manera, los debería escribir como un complemento y luego incluirlos en ActiveRecord volviendo a abrir la definición de la clase. La guía de Ruby on Rails para crear un plugin:
http://guides.rubyonrails.org/plugins.html
Cubre cómo se escribirían tales métodos de plugin / nivel de clase. Es un buen documento sobre cómo entender lo que significan estos tipos de métodos y cómo interactúan con las instancias.
Re: ¿Cómo y cuándo se llaman estos métodos?
[Se llaman cuando la clase está cargada. Puedes poner un punto de interrupción en uno de los métodos y ver que se llama como parte del inicio de tu proyecto de rieles.]
¿Cómo se definen?
[Son métodos de clase. Como esto es ruby, se podrían definir de varias maneras.]
¿Están mixins definidos en algún módulo de registro activo?
[En este caso,
validates_presence_of se define en vendor / rails / activerecord / lib / active_record / validations.rb
belongs_to se define en vendor / rails / activerecord / lib / active_record / associations.rb
ActiveRecord es un gran sistema, incluye muchas mezclas, módulos, etc.
Tenga en cuenta que para ver dónde están definidos los métodos, uso http://www.gotapi.com/rubyrails para cada método, vea el enlace "Mostrar origen" en la parte inferior de la definición.
]
Yehuda Katz tiene una buena explicación de esto en su blog. Ver el punto 4: Los cuerpos de clase no son especiales .