Utilizo la siguiente línea en un inicializador para cargar automáticamente el código en mi /lib
directorio durante el desarrollo:
config / initializers / custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(de Rails 3 Quicktip: recarga automática de carpetas lib en modo de desarrollo )
Funciona muy bien, pero es demasiado ineficiente para usar en producción: en lugar de cargar libs en cada solicitud, solo quiero cargarlas al inicio. El mismo blog tiene otro artículo que describe cómo hacer esto:
config / application.rb:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Sin embargo, cuando cambio a eso, incluso en el desarrollo, obtengo NoMethodErrors cuando intento usar las funciones lib.
Ejemplo de uno de mis archivos lib:
lib / extensions.rb:
Time.class_eval do
def self.milli_stamp
Time.now.strftime('%Y%m%d%H%M%S%L').to_i
end
end
Llamar Time.milli_stamp
arrojará NoMethodError
Me doy cuenta de que otros han respondido preguntas similares sobre SO, pero todos parecen tratar con convenciones de nomenclatura y otros problemas de los que no tenía que preocuparme antes: mis clases de lib ya funcionaban para cargar por solicitud, solo quiero cambiarlo a la carga por inicio . ¿Cuál es la forma correcta de hacer esto?
Respuestas:
Creo que esto puede resolver tu problema:
en config / application.rb :
y mantenga la convención de nomenclatura correcta en lib .
en lib / foo.rb :
en lib / foo / bar.rb :
si realmente quieres hacer algunos parches de mono en un archivo como lib / extensions.rb , puedes requerirlo manualmente:
en config / initializers / require.rb :
PD
Rieles 3 módulos / clases de carga automática por Bill Harding.
¿Y para entender qué hace Rails exactamente sobre la carga automática?
lea la carga automática de Rails: cómo funciona y cuándo no lo hace Simon Coffey.
fuente
config.eager_load_paths << Rails.root.join('lib')
. Sin embargo, eso tiene un gran inconveniente en que tambiéneager_load_paths
carga todo en las tareas. Creo que la solución de lulalala es mejor. Aquí hay una publicación de blog con más detalles: blog.arkency.com/2014/11/…Aunque esto no responde directamente a la pregunta, creo que es una buena alternativa para evitar la pregunta por completo.
Para evitar todo el
autoload_paths
oeager_load_paths
molestia, crear un "lib" o un directorio "misceláneos" en el directorio "aplicación". Coloque los códigos como lo haría normalmente allí, y Rails cargará archivos tal como cargará (y volverá a cargar) archivos de modelo.fuente
app
, necesito hacerlo manualmente ... o necesito ponerlo en la ruta de carga automática ...app/views
directorio que no se agrega; o más bien se elimina explícitamente.lib
está destinado a código que se puede aplicar a múltiples proyectos y posiblemente se pueda extraer a una gema. Si no es así, cree una carpeta más apropiada en la búsqueda de aplicaciones comoservices/
opresenters/
e incluso elimine estas.Esto podría ayudar a alguien como yo que encuentre esta respuesta al buscar soluciones a cómo Rails maneja la carga de la clase ... Descubrí que tenía que definir un
module
nombre cuyo nombre coincidiera con mi nombre de archivo de manera adecuada, en lugar de solo definir una clase:En el archivo lib / development_mail_interceptor.rb (Sí, estoy usando el código de un Railscast :))
funciona, pero no se carga si no hubiera puesto la clase dentro de un módulo.
fuente
LOAD_PATH/module/class.rb
(subrayado) dondeLOAD_PATH
está en las rutas de carga utilizadas por la aplicación Ruby (autoload_paths en el caso de Rails).lib
ha fluctuado de ser cargado automáticamente por Rails a no cargarse automáticamente, y en versiones recientes (> = Rails 3.x) no se carga automáticamente. No se recomienda la magia que haga que esto funcione para usted. Tal vez es un viejo Railscast?Use config.to_prepare para cargar sus parches / extensiones de mono para cada solicitud en modo de desarrollo.
final
fuente