Accessing models from within the lib directory in a Rails 3 project

后端 未结 5 708
天涯浪人
天涯浪人 2021-01-03 06:04

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         


        
相关标签:
5条回答
  • 2021-01-03 06:10

    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.

    0 讨论(0)
  • 2021-01-03 06:13

    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 included 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"
    
    0 讨论(0)
  • 2021-01-03 06:13

    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.

    0 讨论(0)
  • 2021-01-03 06:32

    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
    
    0 讨论(0)
  • 2021-01-03 06:33

    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
    
    0 讨论(0)
提交回复
热议问题