6

Tengo varios métodos de clase personalizados _as _... que me gustaría usar en mi aplicación. Me gustaría que el código para esos métodos esté en los archivos en el directorio de aplicaciones/módulos.¿Cómo puedo extender ActiveRecord desde la aplicación/módulos?

he sido incapaz de conseguir este trabajo.

Por ejemplo, tengo un archivo: app/módulos/acts_as_lockable

module ActsAsLockable 

    def acts_as_lockable 
     before_create :set_lock 

     include InstanceMethods 
    end 

    module InstanceMethods 
     protected 

     def set_lock 
      now = Time.now.to_s 
      self.lock = Digest::SHA1.hexdigest(now) 
     end 
    end 

end 

ActiveRecord::Base.extend ActsAsLockable 

Y en application.rb

config.autoload_paths += %W(#{config.root}/app/modules) 

Cuando intento cargar un modelo que llama acts_as_lockable consigo el siguiente error:

NameError: undefined local variable or method `acts_as_lockable'

Mi conjetura es que yo no fuera la carga automática bec carpeta de módulos ¿Ya se ha cargado ActiveRecord cuando lo extiendo? Hay otra manera de hacer esto? Me gustaría poder modificar el archivo durante el desarrollo sin reiniciar mi servidor, pero eso es más un deseo que una necesidad.

Respuesta

7

creo que está pensando acerca de esto en el camino equivocado.

Va a añadir este módulo a la trayectoria de carga,

pero sólo se cargará si bien dice;

require 'acts_as_lockable' 

o

ActsAsLockable 

me gustaría sugerir que en realidad nunca quieren decir cualquiera de estos dentro de su código.

El paradigma correcto que estás buscando es un "inicializador".

sugiero crear un archivo llamado "config/inicializadores/acts_as_lockable.rb"

En este archivo se puede incluir ya sea todo el código,

o simplemente incluyen un require 'acts_as_lockable'

Normalmente mantener las cosas como esta dentro del directorio libs

asegurar lib se encuentra en la ruta de carga

** config/aplicación.rb **

config.autoload_paths += %W(#{config.root}/lib) 

** lib/acts_as_lockable.rb **

module ActsAsLockable 

    def acts_as_lockable 
    before_create :set_lock 

    include InstanceMethods 
    end 

    module InstanceMethods 
    protected 

    def set_lock 
     now = Time.now.to_s 
     self.lock = Digest::SHA1.hexdigest(now) 
    end 
    end 

end 

entonces en el inicializador

** config/inicializadores/acts_as_lockable.rb **

require 'acts_as_lockable' 
ActiveRecord::Base.extend ActsAsLockable 
+0

Gracias que funcionó como un encanto. Me doy cuenta de que probablemente no sea la solución más práctica, pero por alguna razón odio ver declaraciones incluidas en mis modelos. – tanman

0

El problema es que el mecanismo de carga automática de rubí es un proceso lento: Cuando se utiliza como una constante ActsAsLockable dentro de su código, busca un archivo llamado acts_as_lockable.rb dentro de los autoload_paths. Como en realidad nunca usa ActsAsLockable, el archivo nunca se carga. Usted podría hacer (aunque no tremendamente hermosa):

ActsAsLockable 

class MyModel < ActiveRecord::Base 
    acts_as_lockable 

    ... 
end 

creo que el acts_as_ * patrón es ción para ser utilizada sea plugins y gemas para integrar fácilmente la funcionalidad en el código. Se supone que los complementos y gemas están en un estado final cuando los integra en su proyecto, por lo que no necesitaría la funcionalidad de recarga para el modo de desarrollo.

Espero que esto ayude.

Cuestiones relacionadas