ruby-on-rails - que - ruby on rails tutorial
Rails 3: alias_method_chain aún se usa? (3)
Estaba leyendo sobre el desarrollo de Gems / Plugin para Rails 3 y encontré esta publicación que dice que alias_method_chain ya no se usa. Puedo ver que el método todavía está allí en activesupport-3.0.0 / lib / active_support / core_ext / module / aliasing.rb.
¿Debo seguir usando alias_method_chain en Rails 3?
¿Sigue reflejando las mejores prácticas para gemas / complementos en Rails 3 que desean modificar ActiveRecord?
En general, un módulo nunca puede anular un método en la clase en la que está incluido. Esto se debe a que la inclusión de módulos funciona igual que la creación de subclases. Una superclase tampoco puede anular los métodos de sus subclases, ni lo esperaría.
Cuando se incluye un módulo en una clase, el módulo se inserta justo después de la clase en la cadena de antepasados de la clase. Llamar a super
de la clase llamará a la implementación del módulo .
class Something
module PreExtension; end
module PostExtension; end
include PreExtension
include PostExtension
end
Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
Cada vez que se invoca un método en Something
, Ruby examina esta lista en orden y llama a la primera implementación que encuentra. Si la implementación llama a super
, sigue buscando y encuentra la siguiente.
Esto significa que los módulos incluidos más adelante tienen prioridad sobre los módulos incluidos anteriormente, y pueden llamar a super
para obtener las implementaciones de los módulos anteriores. Esto se debe a que los módulos incluidos se insertan en la cadena ancestral directamente después de la clase. Así es como el código de enrutamiento edgerunner mencionado funciona. Ese código pone todo en módulos, así:
class SomethingNew
module Base
def my_method
puts "(A)"
end
end
module Extension
def my_method
puts "(B)"
super
end
end
include Base
include Extension
end
SomethingNew.new.my_method
# Output:
# >> (B)
# >> (A)
SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
Esta es la razón alias_method_chain
cual alias_method_chain
existió en primer lugar. Si poner el código base en un módulo no es una opción, no estoy seguro de cómo lograr el equivalente de alias_method_chain
.
Veo que alias_method_chain
ya no está presente en Rails 3.0.0. http://api.rubyonrails.org/ no lo informa y la rails console
informa que es undefined local variable or method
.
Ver también - https://rails.lighthouseapp.com/projects/8994/tickets/285-alias_method_chain-limits-extensibility#ticket-285-20
ACTUALIZACIÓN: Según lo observado por @ecoologic en los comentarios, alias_method_chain
todavía está presente en Rails 3.1.1.
No, ha sido reemplazado por un uso inteligente del método anulando en los módulos y la palabra clave super
.
Básicamente, define la función original en un módulo incluido y lo reemplaza en otro módulo incluido. Cuando llama a super
en la función de anulación, llama a la función original. Pero hay una trampa. Debe incluir los módulos extendidos después de incluir el módulo base y en el orden en que desea que se realice el encadenamiento.
class Something
module Base
def my_method
# (A) original functionality
end
end
module PreExtension
def my_method
# (B) before the original
super # calls whatever was my_method before this definition was made
end
end
module PostExtension
def my_method
super # calls whatever was my_method before this definition was made
# (C) after the original
end
end
include Base # this is needed to place the base methods in the inheritance stack
include PreExtension # this will override the original my_method
include PostExtension # this will override my_method defined in PreExtension
end
s = Something.new
s.my_method
#=> this is a twice extended method call that will execute code in this order:
#=> (B) before the original
#=> (A) the original
#=> (C) after the original
Ryan Bates de Railscasts habla sobre cómo se usa esto en el código de Rails Routing . Yo recomendaría verlo, y sus otros screencasts. Tienen el poder de transformar a una abuela que hace punto en un gurú de Rails.
PD: El crédito va para Peeja por corregir un error fundamental en mi respuesta original. Gracias.