2012-07-24 10 views
5

tengo un archivo en el directorio lib que utiliza algunas constantes definidas en un modelo, como:modelos accede desde dentro del directorio lib en un proyecto Rails 3

class User < ActiveRecord::Base 
    MAX_EMAIL_ADDRESS_LENGTH = 255 
end 

y luego tengo en lib/foo. rb

module Foo 
    LONG_EMAIL_ADDRESS = "[email protected]".rjust(User::MAX_EMAIL_ADDRESS_LENGTH, "a") 
end 

No funciona debido a que no se encuentra la clase Usuario. ¿Cómo puedo cargar el usuario antes de ese archivo en lib?

Estoy cargando ese archivo por tener esto en mi application.rb:

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

¿Cómo está usted, incluyendo 'lib' en su aplicación rieles ? En Rails 3 no se carga automáticamente de forma predeterminada, por lo que sería útil mostrar cómo se está accediendo a 'lib/foo.rb'. – deefour

+0

@Deefour, hecho. – Pablo

+0

¿Tiene este módulo incluido? Si es así, ¿dónde está incluido? –

Respuesta

2

la solución fue que mi archivo en/lib en realidad estaba siendo requerido por un archivo de rastrillo, y parece rastrillo archivos se cargan antes de que todo el sistema de carga automática es la configuración por carriles, por lo que no pudo encontrar el modelo. Después de eliminar el requerimiento del archivo .rake, todo comenzó a funcionar.

1

Por defecto, es YourApplicationNameHere::Application.autoload_paths[]. I (solo por razones de organización) agrego un glob para mi directorio app/models también.

config.autoload_paths += Dir["#{Rails.root}/app/models/**/"] 
config.autoload_paths += Dir["#{config.root}/lib"] 

Con esta configuración, puedo hacer lo que me pide en la Pregunta sin problemas. Esto también debería beneficiarlo, indicando a Rails dónde buscar si no puede encontrar el modelo User dentro de la instanciación de su módulo lib/.

Editar

Especificación del mensaje de error exacto en su pregunta habría ayudado también.

uninitialized constant Foo::User 

significa Rubí/Rails está buscando User dentro del espacio de nombres Foo. Prefijo User con :: para forzar la búsqueda del espacio de nombres global.

module Foo 
    LONG_EMAIL_ADDRESS = "[email protected]".rjust(::User::MAX_EMAIL_ADDRESS_LENGTH, "a") 
end 
+0

Eso no funcionó para mí. Intenté varias variaciones y siempre termino con: constante no inicializada Foo :: User. – Pablo

+0

Por favor, mira mi edición. – deefour

0

Parece ser que el usuario no ha de clase se crea una instancia, que parece inusual, a menos que tenga 'user.rb' en una ubicación distinta de 'modelos'. A menudo ocurre que las clases no se cargan en desarrollo a menos que estén específicamente en ese directorio, pero una solución que uso es esta línea que puede poner solo dentro de su código que espera que se llame antes de la línea ofensiva que tiene ..

Rails.application.eager_load! if Rails.env == "development" 

La parte condicional es probablemente innecesario, pero lo incluyo sólo para estar seguro de su efecto sólo se produce en el desarrollo.

1

La primera parte se hizo bien:

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

A continuación, es importante, módulo de

module Foo 
    ... 
end 

debe ser colocado en un archivo

lib/foo.rb 

.

Y luego, puede ser include d en el código de la aplicación.

class Comment < ActiveRecord::Base 
    include Foo 
    ... 
end 

Si el archivo de foo.rb lib no está destinado a ser incluido (sin embargo, es probablemente una manera incorrecta), a continuación, utilizar modelos Rails y otras cosas dentro de este código que debe poner esto en foo.rb:

require_relative "../config/environment.rb" 
+0

No estoy intentando acceder a una lib desde un modelo, sino a un modelo de un archivo lib. – Pablo

+0

Así que intente 'require_relative" ../ config/environment.rb "' –

2

Sé que esta es una vieja pregunta, pero acabo de enfrentar el mismo problema y después de algunas búsquedas, encontré una solución, así que creo que vale la pena compartirlo.

Quería usar un modelo "Foo" en uno de los archivos necesarios ubicados en mi directorio/lib. En primer lugar, he hecho esto y no funcionó:

# in my rake file 
task :foo_task do 
    require /some_path/lib/bar.rb 
end 

# in /lib/bar.rb 
puts "Foo = #{Foo.count} " 

# => uninitialized constant Foo 

Después de algunas búsquedas, he encontrado que los modelos de acceso a los archivos en mi lib, necesito especificar el medio ambiente en mi tarea. Así que me acaba de agregar esto a mi declaración tarea:

task :foo_task => [:environment] do 

Ahora, cuando llamo a mi tarea, se pone correctamente el número de Foo:

# => Foo = 6 
Cuestiones relacionadas