Where should I place my own "module" within rails application?
Some functionality within my rails application looks better as if it was a separate "module", that should be accessed via require
. For example, assume it's a function to calculate Fibonacci numbers.
The functionality is independent on rails application and can be reused in other projects, so it should not be stored near application controllers and models, I suppose. But since I'm not going to detach it into separate project, thus placing it to 开发者_JAVA百科vendor
folder seems like not the right thing.
Where should I place it then?
Rails < 5
Before Rails 5, the place to put reusable code such as this is in the lib
directory. However you do not need to require
anything as lib
is already in the load path and it's contents will be loaded during initialization.
If you need to extend an existing class, you define your module first and then include it by sending it as a message to the class you wish to extend, e.g.
module MyExtensions
def self.included base
base.instance_eval do
def my_new_method
…
end
end
end
end
ActiveRecord::Base.send :include, MyExtensions
Rails 5+
The answer is for Rails 5 onwards. TLDR: app/lib
is the convention now.
- Note all the above answers were written before Rails 5.
\lib
Rails 5 discourages you from using \lib
. While you are discouraged from using \lib you still can as long as you add \lib to eagerloading.
# config/application.rb
config.eager_load_paths << Rails.root.join('lib')
\app\lib
Nesting lib off app is now a common convention because any directory off app is automatically eagerloaded.
Reference
Rails guide - autoloading and eagerloading
Stackoverflow - confusing about autoload_paths vs eager_load_paths in rails 4
Stackoverflow - Why use app-lib instead of lib in rails
There is a lib directory in RoR projects which fits well for that purpose - I place common bits of code in form of "libraries" there. Anything from extending ActiveRecord classes to reusable utility methods.
I'll often put stuff in lib
, it turns out that anything under lib is in the load path and doesn't need to be require
d at all.
edit: After Steve's comment, removed the bit about having to require the files. Also, removed a couple requires from some of my code :P
精彩评论