tutorial rails que ejemplos descargar curso caracteristicas ruby-on-rails ruby

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 .



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.