I have a file in the lib directory that uses some constants defined in a model, like:
class User < ActiveRecord::Base
MAX_EMAIL_ADDRESS_LENGTH = 255
en
The solution was, that my file in /lib was actually being required by a rake file, and it seems rake files are loaded before the whole auto-load system is setup by Rails, so it couldn't find the model. After I remove the require from the .rake file, everything started working.
The first part was done right:
config.autoload_paths += %W(#{config.root}/lib)
Next, it is important, module
module Foo
...
end
must be placed into
lib/foo.rb
file.
And then, it can be include
d into application code.
class Comment < ActiveRecord::Base
include Foo
...
end
If file foo.rb
from lib directory is not intended to be included (however it is probably a wrong way), then to use Rails models and other stuff inside this code you should put this into foo.rb:
require_relative "../config/environment.rb"
It appears that your class User has not be instantiated, which seems unusual, unless you have 'user.rb' in a location other than 'models'. It is often the case that classes aren't loaded in development unless they are specifically in that directory, but one solution I use is this line that you could put just within your code that you expect to be called prior to the offending line you have..
Rails.application.eager_load! if Rails.env == "development"
The conditional part is probably unnecessary, but I include it just to be certain its effect only occurs in development.
By default, YourApplicationNameHere::Application.autoload_paths
is []
. I (purely for organizational reasons) add a glob for my app/models
directory too.
config.autoload_paths += Dir["#{Rails.root}/app/models/**/"]
config.autoload_paths += Dir["#{config.root}/lib"]
With this setup I'm able to do what you're asking in the Question without trouble. This should benefit you as well, telling Rails where to look if it can't find the User
model from within your lib/
module's instantiation.
Edit
Specifying the exact error message in your question would have helped too.
uninitialized constant Foo::User
means Ruby/Rails is looking for User
within the Foo
namespace. Prefix User
with ::
to force the lookup to the global namespace.
module Foo
LONG_EMAIL_ADDRESS = "foo@bar.com".rjust(::User::MAX_EMAIL_ADDRESS_LENGTH, "a")
end
I know this is a old question but I've just faced the same problem and after some searches, I found a solution so I think it worth to share it.
I wanted to use a model "Foo" in one required files located in my /lib directory. First, I did this and it didn't work :
# 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
After some searches, I found that to access models in my lib's files, I need to specify the environment in my task. So I just added this to my task declaration :
task :foo_task => [:environment] do
Now, when I call my task, it correctly puts the number of Foo :
# => Foo = 6