2010-11-02 8 views
73

pongo un nombre de archivo en el lado g.rb Rails.root/lib carpeta El contenido del archivo es la siguiente:Adición lib a '' config.autoload_paths en Rails 3 no autocarga mi módulo

module Google 
end 

Luego añadir

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

a mi Rails.root/config/application.rb

Sin embargo, cuando intento de invocar a Google de rails console, se produce una excepción. La excepción desaparece solo si ejecuto require 'google'. ¿Por qué? ¿No debería mi archivo estar cargado automáticamente y no debería acceder al módulo sin ninguna declaración adicional de require?

Respuesta

112

Hmm, descubrí algo interesante. Para que Rails cargue automáticamente mi clase, el nombre de la clase debe ser compatible con el nombre del archivo y la estructura de la carpeta. Por ejemplo, si quiero que el módulo de Google esté cargado automáticamente, debo colocarlo dentro de google.rb, directamente debajo de/lib (en caso de que especifique autocarga de/lib). Si quiero carga automática Google::Docs, entonces o bien se coloca dentro google.rb o google/docs.rb

+6

así es esto un error o una convención? – Blankman

+8

Creo que esto es una convención. Rails toma nombres constantes y los convierte en rutas de acceso. :: se convierte en/para este propósito. Entonces Google :: Docs se convierte en google/docs.rb. Podría debatir sobre la utilidad de esto, pero esa es mi comprensión de la funcionalidad actual. –

+3

No es una convención per se, es la forma en que el intérprete de Ruby busca cosas, por lo que sé – Ghoti

1

que enfrentan el mismo problema hace un momento, y mi "solución" (o más bien solución) fue requerir manualmente todos los archivos necesarios de los carriles. root/lib en mi application.rb.

require 'lib/message' 
require 'lib/store' 
require 'lib/vault/vault.rb' 
require 'lib/custom_loggers' 

module MyApplication 
    class Application < Rails::Application 

Mi próximo paso sería categorizar los archivos en las carpetas del módulo como usted menciona.

+1

Stephen G tiene una buena respuesta. – Mirko

+0

Hola @morbaq, hoy tuve el mismo problema y tu solución funciona a la perfección, solo quería agradecerte: D – sameera207

24

Eso es porque el punto de autocarga es no para 'requerir' todo por adelantado (penalización de inicio). Las clases se cargan cuando se necesitan/referencian. Para hacer esto, necesitas alguna forma de saber dónde buscar la clase. De lo contrario, tendría que cargar todos los archivos en el directorio de carga automática de antemano para ver qué clases están declaradas. Es una compensación, pero requiere todo por adelantado (como sugiere marbaq) no es automático. Puede usar el comando autoload proporcionado por Ruby, que toma dos argumentos, el módulo para cargar (simbolizado, es decir: Google en su caso), y el segundo argumento es el nombre de archivo, que sería g.rb si lib está en su ruta de carga ($ :). Consulte los documentos de Ruby para autocarga.

+1

Por cierto, la convención dice que solo debes renombrar lib/g.rb a lib/google.rb y estar en camino . –

27

Tuve un problema similar al hacer que mi módulo se ejecutara en Heroku. Además de la convención de nomenclatura de autocargador establecida por Stephen C, descubrí que el código del módulo debe ser require 'd debido a una suposición threadsafe hecha por el entorno de producción de Rails en Heroku (aunque threadsafe se comentó en mi archivo de configuración production.rb .) Tan pronto como yo require 'd el archivo del módulo antes de llamar al include en el módulo, todo comenzó a funcionar.

require 'mymodule' 
include Mymodule 

favor, eche un vistazo a this excellent article sobre el tema de conseguir módulos para cargar correctamente en Heroku (producción).

+0

+1 Esta debería ser la respuesta aceptada. El enlace debería ayudar a cualquiera y la seguridad de las secuencias era en realidad mi problema. Gracias. –

-5

i conocer esta solución recientemente

config/aplicación.rb

module AppName 
    class Application < Rails::Application 

    # Custom directories with classes and modules you want to be autoloadable. 
    config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')] 
    config.autoload_paths += Dir[Rails.root.join('app', 'lib', 'extensions')] 

    end 
end 

la primera llamada de configuración induce a los carriles de carga automática todos los subdirectorios del directorio app/models por lo que ahora puedo tener /app/models/sub_directory/model.rb auto-cargado (útil para la organización de una aplicación con una gran base de código)

la segunda llamada config induce a los carriles de carga automática el directorio lib/extensiones

esperanza esto ayuda

nota: Creo que esto es raíles 3 específicos

Cuestiones relacionadas