ruby on rails - ¿La mejor manera de cargar el módulo/clase de la carpeta lib en Rails 3?
ruby-on-rails class (12)
La magia del autoloading.
Creo que la opción de controlar 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 con la carga, a pesar de que se hayan modificado sus rutas de carga automática según sea necesario, entonces esta respuesta intenta explicar cuál es la magia detrás de esta cosa de carga automática.
Entonces, cuando se trata de cargar cosas desde subdirectorios, hay una Gotcha o una convención que debes tener en cuenta. A veces, la magia de Ruby / Rails (esta vez principalmente Rails) puede hacer que sea difícil entender 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 en lib/my_stuff/bar.rb
algo como:
module Foo
class Bar
end
end
No se cargará automáticamente. Entonces, de nuevo, si cambia el nombre del directorio principal a foo
, aloja el módulo en la ruta: lib/foo/bar.rb
Estará ahí para ti. Otra opción es nombrar el archivo que desea que el nombre del módulo cargue automáticamente. Obviamente, entonces solo puede haber un archivo con ese nombre. En caso de que necesite dividir sus cosas en muchos archivos, por supuesto podría usar ese archivo para requerir otros archivos, pero no lo recomiendo, porque luego, cuando está en modo de desarrollo y modifica esos otros archivos, Rails no puede hacerlo automáticamente. recárgalos por ti. Pero si realmente desea, puede tener un archivo por el nombre del módulo que luego especifica los archivos reales necesarios para usar el módulo. Por lo tanto, podría tener dos archivos: lib/my_stuff/bar.rb
y lib/my_stuff/foo.rb
y el primero es el mismo que el anterior y el último contiene una sola línea: require "bar"
y funcionaría igual.
PD Me siento obligado a añadir una cosa más importante. Últimamente, cada vez que quiero tener algo en el directorio lib que necesita ser cargado automáticamente, tiendo a pensar que si es algo que realmente estoy desarrollando específicamente para este proyecto (que generalmente es así, podría algún día conviértalo en un fragmento de código "estático" usado en muchos proyectos o en un submódulo de git, etc. en cuyo caso definitivamente debería estar en la carpeta lib), entonces quizás su lugar no esté en la carpeta lib en absoluto. Tal vez 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 cargues automáticamente tus cosas, así que es bueno para estas cosas. De todos modos, esto es sólo mis pensamientos sobre el tema. Usted es libre de estar en desacuerdo. :)
ACTUALIZACIÓN: Sobre el tipo de magia ..
Como Severin señaló en su comentario, el núcleo "carga automática de un mecanismo de módulo" seguramente es parte de Ruby, pero las cosas de la carga automática no lo son. No necesita Rails para realizar la autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. Y cuando intentes consultar el módulo Foo por primera vez, se cargará para ti. Sin embargo, lo que hace Rails es que nos da una forma de intentar cargar cosas automáticamente desde carpetas registradas y esto se ha implementado de tal manera que debe asumir algo acerca de las convenciones de nomenclatura. Si no se hubiera implementado así, entonces cada vez que haga referencia a algo que no está cargado en ese momento, tendrá que revisar todos los archivos en todas las carpetas de carga automática y verificar si alguno de ellos contiene algo a lo que estaba tratando de hacer referencia. Esto, a su vez, anularía la idea de carga automática y carga automática. Sin embargo, con estas convenciones en su lugar, puede deducir del módulo / clase que intenta cargar donde podría definirse y simplemente cargar eso.
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?
Desde 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);
A partir de Rails 5
, se recomienda colocar la carpeta lib en el directorio de la aplicación o, en su lugar, crear otros espacios de nombres significativos para la carpeta como services
, presenters
, features
, etc. y colocarla en el directorio de la aplicación para que se carguen automáticamente mediante rieles.
Por favor revise este enlace de discusión de GitHub también.
Advertencia: si desea cargar el ''parche de mono'' o la ''clase abierta'' desde su carpeta ''lib'', ¡¡¡no use el enfoque de ''carga automática'' !
Enfoque de " config.autoload_paths ": solo funciona si está cargando una clase que definió solo en UN lugar. Si alguna clase ya se ha definido en otro lugar, no puede volver a cargarla con este método.
" config/initializer/load_rb_file.rb " enfoque: ¡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: config/initializer/load_rb_file.rb
En mi caso, estaba intentando simplemente cargar un archivo directamente bajo el directorio lib.
Dentro de application.rb ...
require ''/lib/this_file.rb''
No funcionaba, incluso en consola y luego cuando lo intenté.
require ''./lib/this_file.rb''
y rieles carga el archivo perfectamente.
Todavía soy bastante novato y no estoy seguro de por qué funciona esto, pero funciona. Si alguien quisiera explicármelo, lo apreciaría: Espero que esto ayude a alguien de cualquier manera.
Hay varias razones por las que podría tener problemas al cargar desde lib. Consulte aquí para obtener más información: http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
- arreglar la ruta de carga automática
- relacionado con threadsafe
- relacionando nombres
- ...
Muy similar, pero creo que esto es un poco más elegante:
config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]
Si solo ciertos archivos necesitan acceso a los módulos en lib, simplemente agregue una declaración de requerimiento a los archivos que lo necesitan. Por ejemplo, si un modelo necesita acceder a un módulo, agregue:
require ''mymodule''
en la parte superior del archivo model.rb.
Yo tuve el mismo problema. Así es como lo resolví. La solución carga el directorio lib y todos los subdirectorios (no solo los directos). Por supuesto que puedes usar esto para todos los directorios.
# application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
config.autoload_paths no funciona para mí. Lo resuelvo de otra manera.
Ruby on rails 3 no recarga automáticamente el código de la carpeta / lib. Lo resuelvo poniendo dentro
ApplicationController
Dir["lib/**/*.rb"].each do |path|
require_dependency path
end
A partir de Rails 2.3.9 , hay una configuración en config/application.rb
en la que puede especificar los directorios que contienen archivos que desea que se carguen automáticamente.
Desde application.rb:
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
Deletrea 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 / Governance / architecture_baord.rb (transpuesto O y A en "tablero")
Parece obvio en retrospectiva, pero fue el demonio el que lo rastreó. Si la clase no está definida en el archivo en el que Rails espera que esté en función de munging el nombre de la clase, simplemente no lo va a encontrar.
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Tenga en cuenta que los archivos contenidos en la carpeta lib solo se cargan cuando se inicia el servidor. Si desea tener la comodidad de cargar automáticamente esos archivos, lea: Rails 3 Quicktip: Cargue automáticamente las carpetas lib en modo de desarrollo . Tenga en cuenta que esto no está pensado para un entorno de producción, ya que la recarga permanente ralentiza la máquina.