Dado que la última versión de Rails 3 ya no es la carga automática de módulos y clases desde lib, ¿cuál sería la mejor manera de cargarlos?
De github:
A few changes were done in this commit: Do not autoload code in *lib* for applications (now you need to explicitly require them). This makes an application behave closer to an engine (code in lib is still autoloaded for plugins);
app/lib
.Fuente: Rails 3 Sugerencia rápida: directorio lib de carga automática que incluye todos los subdirectorios, evite la carga diferida
Tenga en cuenta que los archivos contenidos en la carpeta lib solo se cargan cuando se inicia el servidor. Si desea la comodidad de volver a cargar automáticamente esos archivos, lea: Rails 3 Sugerencia rápida: recargue automáticamente las carpetas lib en modo de desarrollo . Tenga en cuenta que esto no está destinado a un entorno de producción, ya que la recarga permanente ralentiza la máquina.
fuente
La magia de la carga automática
Creo que la opción que controla las carpetas desde las que se realiza la carga automática se ha cubierto suficientemente en otras respuestas. Sin embargo, en caso de que alguien más tenga problemas cargándose aunque hayan modificado sus rutas de carga automática según sea necesario, esta respuesta intenta explicar cuál es la magia detrás de esta carga automática.
Entonces, cuando se trata de cargar cosas desde subdirectorios, hay una trampa o una convención que debes tener en cuenta. A veces, la magia Ruby / Rails (esta vez principalmente Rails) puede dificultar la comprensión de por qué sucede algo. Cualquier módulo declarado en las rutas de carga automática solo se cargará si el nombre del módulo corresponde al nombre del directorio principal. Entonces, en caso de que intentes poner
lib/my_stuff/bar.rb
algo como:No se cargará automáticamente. Por otra parte, si cambia el nombre del directorio padre de
foo
alojamiento tanto en el módulo de ruta:lib/foo/bar.rb
. Estará allí para ti. Otra opción es nombrar el archivo que desea cargar automáticamente con el nombre del módulo. Obviamente, solo puede haber un archivo con ese nombre. En caso de que necesite dividir sus cosas en muchos archivos, por supuesto, puede usar ese archivo para requerir otros archivos, pero no lo recomiendo, porque cuando esté en modo de desarrollo y modifique esos otros archivos, Rails no podrá automaticamente Vuelva a cargarlos para usted. Pero si realmente lo desea, podría tener un archivo con el nombre del módulo que luego especifique los archivos reales necesarios para usar el módulo. Por lo tanto, podría tener dos archivos:lib/my_stuff/bar.rb
ylib/my_stuff/foo.rb
el primero es el mismo que el anterior y el último contiene una sola línea:require "bar"
y eso funcionaría igualPD: Me siento obligado a agregar una cosa más importante. Últimamente, cada vez que quiero tener algo en el directorio lib que necesita cargarse automáticamente, tiendo a empezar a pensar que si esto es algo que realmente estoy desarrollando específicamente para este proyecto (que suele ser, algún día podría se convierta en un fragmento de código "estático" utilizado en muchos proyectos o en un submódulo git, etc. en cuyo caso definitivamente debería estar en la carpeta lib), entonces tal vez su lugar no esté en la carpeta lib en absoluto. Quizás debería estar en una subcarpeta debajo de la carpeta de la aplicación · Tengo la sensación de que esta es la nueva forma de hacer las cosas. Obviamente, la misma magia está en el trabajo en cualquier lugar en el que cargue automáticamente los caminos en los que coloque sus cosas, por lo que es bueno para estas cosas. De todos modos, esto es solo mis pensamientos sobre el tema. Eres libre de estar en desacuerdo. :)
ACTUALIZACIÓN: Sobre el tipo de magia ...
Como severin señaló en su comentario, el núcleo "mecanismo de carga automática de un módulo" es parte de Ruby, pero las cosas de las rutas de carga automática no lo son. No necesitas rieles para hacer
autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. Y cuando intentes hacer referencia al módulo Foo por primera vez, se cargará por ti. Sin embargo, lo que hace Rails es que nos brinda una forma de intentar cargar cosas automáticamente desde carpetas registradas y esto se ha implementado de tal manera que debe asumir algo sobre las convenciones de nomenclatura. Si no se hubiera implementado así, cada vez que haga referencia a algo que no está cargado actualmente, tendría que revisar todos los archivos en todas las carpetas de carga automática y verificar si alguno de ellos contiene lo que estaba tratando de hacer referencia. Esto a su vez derrotaría la idea de la carga automática y la recarga automática. Sin embargo, con estas convenciones en su lugar, puede deducir del módulo / clase su intento de cargar donde se podría definir y simplemente cargar eso.fuente
Advertencia: si desea cargar el 'parche de mono' o 'clase abierta' desde su carpeta 'lib', ¡no use el enfoque de 'carga automática' !
Enfoque " config.autoload_paths ": solo funciona si está cargando una clase que se definió solo en UN lugar. Si alguna clase ya se ha definido en otro lugar, este enfoque no puede volver a cargarla.
"Enfoque config / initializer / load_rb_file.rb ": ¡siempre funciona! cualquiera que sea la clase objetivo es una nueva clase o una "clase abierta" o "parche de mono" para la clase existente, ¡siempre funciona!
Para obtener más detalles, consulte: https://stackoverflow.com/a/6797707/445908
fuente
Muy similar, pero creo que esto es un poco más elegante:
fuente
En mi caso, estaba tratando de cargar un archivo directamente bajo el directorio lib.
Dentro de application.rb ...
no funcionaba, incluso en la consola y luego cuando intenté
y rails carga el archivo perfectamente.
Todavía soy bastante novato y no estoy seguro de por qué funciona, pero funciona. Si alguien quisiera explicármelo, lo agradecería: espero que esto ayude a alguien de cualquier manera.
fuente
Yo tuve el mismo problema. Así es como lo resolví. La solución carga el directorio lib y todos los subdirectorios (no solo el directo). Por supuesto, puede usar esto para todos los directorios.
fuente
Expected lib/bar/foo.rb to define constant Foo
si intenta cargar lib / foo.rb haciendo referencia al Foo constante.config.autoload_paths no funciona para mí. Lo resuelvo de otra manera
fuente
Si solo ciertos archivos necesitan acceso a los módulos en lib, simplemente agregue una declaración require a los archivos que lo necesitan. Por ejemplo, si un modelo necesita acceder a un módulo, agregue:
en la parte superior del archivo model.rb.
fuente
require
dentro de una aplicación de rieles, ya que impideActiveSupport::Dependencies
[des] cargar ese código correctamente. En su lugar, debe usarconfig.autoload_paths
como la respuesta anterior y luego incluir / extender según sea necesario.require
de ninguna parte de una aplicación Rails? En una tarea de rastrillo, actualmente estoyrequire
-ing yinclude
-ing un módulo que vive enlib/
. ¿No debería estar haciendo eso?require
sulib/
código (por ejemplo, esta publicación de blog , esta respuesta SO ). Todavía no estoy seguro de todo el asunto. ¿Puedes dar más evidencia detrás del reclamo por no usarrequire
?Deletree el nombre de archivo correctamente.
Seriamente. Luché con una clase durante una hora porque la clase era Governance :: ArchitectureBoard y el archivo estaba en lib / gobierno / architecture_baord.rb (O y A transpuestos en "tablero")
Parece obvio en retrospectiva, pero fue el demonio quien lo rastreó. Si la clase no está definida en el archivo en el que Rails espera que esté basada en mezclar el nombre de la clase, simplemente no la encontrará.
fuente
En fecha
Rails 5
, se recomienda poner la carpeta lib en el directorio de aplicaciones o en lugar de crear otros espacios de nombres significativos para la carpeta comoservices
,presenters
,features
etc., y ponerlo en el directorio de aplicaciones para la carga automática de los carriles.Compruebe también este enlace de discusión de GitHub .
fuente
Hay varias razones por las que podría tener problemas para cargar desde lib: consulte aquí para obtener más detalles: http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
fuente