2011-03-06 12 views
5

trato de hacer esto:Rieles: devoluciones de llamada de módulo

app/modelos/my_model.rb:

class MyModel < ActiveRecord::Base 
    include MyModule 
    ... 
end 

lib/my_module.rb:

module MyModule 
    before_destroy :my_func #! 

    def my_func 
    ... 
    end 
end 

pero me da una error:

undefined method `before_destroy' for MyModule:Module 

¿Cómo puedo corregirlo.

También soy nuevo en ruby. ¿Qué tipo tiene estos "atributos": before_destroy, validates, has_many? ¿Son variables o métodos o qué? Gracias

Respuesta

14

before_destroy, validates, etc. no son atributos ni nada de eso. Estas son llamadas a métodos.

En ruby, el cuerpo de una clase es todo código ejecutable, lo que significa que cada línea del cuerpo de la clase es ejecutada por el interpetador como lo haría un cuerpo de método.

before_destroy :my_func es una llamada a método Ruby habitual. El método que se llama es before_destroy, y recibe un símbolo :my_func como argumento. Este método se busca en la clase (o módulo) en el ámbito del cual se llama.

Pasemos ahora a su pregunta, creo que ahora usted debe entender que cuando el intérprete se carga el módulo de

module MyModule 
    before_destroy :my_func #! 

    def my_func 
    ... 
    end 
end 

de que comience la ejecución de su cuerpo y busca el método before_destroy en este módulo y no puede encontrar uno. Lo que quiere hacer es llamar a este método no en el módulo, sino en la clase donde está incluido el módulo. Para eso tenemos una expresión común usando el método Module#included:

module MyModule 
    module InstanceMethods 
    def my_func 
     ... 
    end 
    end 

    def self.included(base) 
    base.send :include, InstanceMethods 
    base.before_destroy :my_func 
    end 
end 
0

en lib/my_module.rb, haga lo siguiente:

 
    class MyInheritedClass < ActiveRecord::Base 
    before_destroy :my_func 
    def my_func 
     ... 
    end 
    end 

en APP/modelos/my_model.rb, haga lo siguiente:

 
class MyModel < MyInheritedClass 
    ... 
end 

no hay un filtro before_destroy en el módulo estás tratando de crear arriba. Lo que mi código hace es crear una clase que heredará de ActiveRecord :: Base y esa será su clase de plantilla de la que todas las otras clases pueden heredar. La clase de plantilla también contiene todas las propiedades de ActiveRecord :: Base.

0

u puede corregir esto quitando before_destroy de MyModule y colocarlo en su lugar MyModel

before_destroy devoluciones de llamada y otros sólo están disponibles para las clases que se extiende ActiveRecord :: Base, más información here

esperanza esto ayuda =)

Cuestiones relacionadas