views:

71

answers:

4

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.

+2  A: 

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

Cody Caughlan
+1  A: 

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.

Emily
+3  A: 

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.

floyd
Very helpful. I'd just always used the naming convention, so didn't know it wouldn't work if I didn't.
Emily
A: 

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
Tim Snowhite