Skip to content

Instantly share code, notes, and snippets.

@maxim
Last active January 9, 2025 00:59
Show Gist options
  • Save maxim/6503591 to your computer and use it in GitHub Desktop.
Save maxim/6503591 to your computer and use it in GitHub Desktop.
How to use rails load paths, app, and lib directories.

In Rails 3

If you add a dir directly under app/

Do nothing. All files in this dir are eager loaded in production and lazy loaded in development by default.

If you add a dir under app/something/

(e.g. app/models/concerns/, app/models/products/)

Ask: do I want to namespace modules and classes inside my new dir? For example in app/models/products/ you would need to wrap your class in a module Products.

If the answer is yes, do nothing. It will just work. If the answer is no, add config.autoload_paths += %W( #{config.root}/app/models/products ) to your application.rb.

If you add code in your lib/ directory

Option 1

If you put something in the lib/ dir, what you are saying is: "I wrote this library, and I want to depend on it where I decide." This means that if you use your library in a rake task, but not in a rails app, you just require it in your rake task. If you need this library to always be loaded for your rails app, you require it in an initializer. If you need this library for some of your models or controllers, you require it in those files, and since everything under your app is already auto- and eager-loaded as needed, in development your library will only be pulled in if a constant that requires it was triggered.

Option 2 (bad)

Another option is to add your whole lib dir into autoload_paths: config.autoload_paths += %W( #{config.root}/lib ). This means you shouldn't explicitly require your lib anywhere. As soon as you hit the namespace of your dir in other classes, rails will require it. The problem with this is that in Rails 3 autoload paths are not eager loaded in production. And in ruby 1.9 autoload is not threadsafe. You probably want eager loading in production. Requiring your lib explicitly, like in option 1, is akin to eager loading it, which is threadsafe.

Organizing lib

In your lib/ dir you should structure your code as if you structure a gem. If you need more than 1 file, you could for example add a same-named directory where everything is properly namespaced, and let your 1 file relatively require files in that directory.

@lesterz
Copy link

lesterz commented Nov 12, 2013

Thank you! This posting finally explained what I was looking for.

@belgoros
Copy link

I still can't figure out where to put/how to load Devise customised strong_parameters for Rails 4.0. At Devise Wiki http://devise.plataformatec.com.br/#getting-started/strong-parameters, it is explained how but not where to put the below code:

class User::ParameterSanitizer < Devise::ParameterSanitizer
  def sign_in
    default_params.permit(:username, :email)
  end
end

I tried all the proposed solutions but none of them worked, - I just never enter inside the above class. Do you have any idea ?
Actually I put it in models folder as follows: models/user/parameter_sanitizer.rb and it worked. Any better idea, may be to put in lib folder ?
Thanks.

@marclennox
Copy link

Awesome post, very well explained and makes total sense.

@kelso
Copy link

kelso commented Apr 30, 2014

I am amazed! Thank you very much for this article, it's very well explained.

@s-ashwinkumar
Copy link

Tried using the Option 1. Throws an error in production on heroku saying "No such file to load" for the file used from lib folder. Any suggestions ?

@hasghari
Copy link

This was driving me crazy in development. require_dependency is exactly what I wanted. 👍

@barberj
Copy link

barberj commented Sep 21, 2014

All files in this dir are eager loaded in production and lazy loaded in development by default. is there a config to make them eager loaded in production?

@hhameed
Copy link

hhameed commented Apr 23, 2016

thanks a lot man, you saved me a lot of time and headache......

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment