When and where do I require files in a rails application?

Viewed 31034

Let's say I have I have the following file in my lib directory of my rails application:

#lib/proxy.rb
module SomeService
  class ServiceProxy
    def do_something
    end
  end
end

If I want to use ServiceProxy in a model, I can use it like so:

#app/models/product.rb
require 'proxy'

class Product < ActiveRecord::Base
  def do_something
    proxy = SomeService::ServiceProxy.new
    proxy.do_something
  end
end

This works, but I noticed if I want to use ServiceProxy in another model, I do not need "require 'proxy'" in the second model file. It seems having "require 'proxy'" once in any model will add it to the lookup path.

Can someone explain this behavior and the best practice surrounding it in a rails app?

Thanks!

UPDATE: Based on floyd's answer below, if my ServiceProxy file was saved as so,

#lib/some_service/service_proxy.rb

then I would not have to explicitly require the file.

6 Answers

This is a helpful post about this issue.

In short, Rails autoloads classes in your lib directory only if they follow the proper naming conventions.

I would generally place that require statement in a config/initalizer file, e.g. config/initializers/load_proxy.rb

Have you tried removing it from the first model as well? I believe Rails will automatically load any files you have in your lib directory without you ever having to require them explicitly.

Also note that some environment.rb's come with these comments:

Rails::Initializer.run do |config|
  # Add additional load paths for your own custom dirs
  # config.load_paths += %W( #{RAILS_ROOT}/extras )
  config.load_paths << "#{RAILS_ROOT}/app/models/some_model_group"
  config.load_paths << "#{RAILS_ROOT}/lib"
end

This article also very helpful for this issue.

The require method takes the name of the file to require, as a string, as a single argument. This can either be a path to the file, such as ./lib/some_library.rb, or a shortened name, such as some_library. If the argument is a path and complete filename, the require method will look there for the file. However, if the argument is a shortened name, the require method will search through a number of pre-defined directories on your system for that file. Using the shortened name is the most common way of using the require method.

Related