Auto-loading lib files in Rails 4

前端 未结 4 1688
陌清茗
陌清茗 2020-11-22 16:20

I use the following line in an initializer to autoload code in my /lib directory during development:

config/initializers/custom.rb:

相关标签:
4条回答
  • 2020-11-22 16:23

    Though this does not directly answer the question, but I think it is a good alternative to avoid the question altogether.

    To avoid all the autoload_paths or eager_load_paths hassle, create a "lib" or a "misc" directory under "app" directory. Place codes as you would normally do in there, and Rails will load files just like how it will load (and reload) model files.

    0 讨论(0)
  • 2020-11-22 16:26

    Use config.to_prepare to load you monkey patches/extensions for every request in development mode.

    config.to_prepare do |action_dispatcher|
     # More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
     Rails.logger.info "\n--- Loading extensions for #{self.class} "
     Dir.glob("#{Rails.root}/lib/extensions/**/*.rb").sort.each do |entry|
       Rails.logger.info "Loading extension(s): #{entry}"
       require_dependency "#{entry}"
     end
     Rails.logger.info "--- Loaded extensions for #{self.class}\n"
    

    end

    0 讨论(0)
  • 2020-11-22 16:28

    I think this may solve your problem:

    1. in config/application.rb:

      config.autoload_paths << Rails.root.join('lib')
      

      and keep the right naming convention in lib.

      in lib/foo.rb:

      class Foo
      end
      

      in lib/foo/bar.rb:

      class Foo::Bar
      end
      
    2. if you really wanna do some monkey patches in file like lib/extensions.rb, you may manually require it:

      in config/initializers/require.rb:

      require "#{Rails.root}/lib/extensions" 
      

    P.S.

    • Rails 3 Autoload Modules/Classes by Bill Harding.

    • And to understand what does Rails exactly do about auto-loading?
      read Rails autoloading — how it works, and when it doesn't by Simon Coffey.

    0 讨论(0)
  • 2020-11-22 16:29

    This might help someone like me that finds this answer when searching for solutions to how Rails handles the class loading ... I found that I had to define a module whose name matched my filename appropriately, rather than just defining a class:

    In file lib/development_mail_interceptor.rb (Yes, I'm using code from a Railscast :))

    module DevelopmentMailInterceptor
      class DevelopmentMailInterceptor
        def self.delivering_email(message)
          message.subject = "intercepted for: #{message.to} #{message.subject}"
          message.to = "myemail@mydomain.org"
        end
      end
    end
    

    works, but it doesn't load if I hadn't put the class inside a module.

    0 讨论(0)
提交回复
热议问题