[ACCEPTED]-How are require, require_dependency and constants reloading related in Rails?-require

Accepted answer
Score: 137

require (and its cousin load) are core Ruby methods. require_dependency is 50 a method that helps Rails handle the problem 49 of dependency management. Long story short, it 48 allows Rails to reload classes in development 47 mode so that you don't have to restart the 46 server each time you make a code change. The 45 Rails framework will require_dependency your code so that 44 it can track and reload it when changes 43 are made. The standard Ruby require doesn't do 42 that. As an app (or plugin/engine) developer 41 you should not have to worry about require_dependency as this 40 is purely internal to Rails.

The magic of 39 the Rails class loading process is in the 38 ActiveSupport::Dependencies module. This 37 code extends the default Ruby behavior to 36 allow code inside your Rails app to automatically 35 load modules (including classes which inherit 34 from Module) using Rails' path and file 33 naming conventions. This eliminates the 32 need for the programmer to litter their 31 code with require calls like you would in a plain 30 Ruby application.

To put it another way, this 29 lets you define class Admin::User inside the file app/models/admin/user.rb and have 28 Rails know what you are talking about when 27 you call Admin::User.new from another part of the application 26 like a controller. Without ActiveSupport::Dependencies 25 involved you would have to manually require everything 24 you needed.

If you are coming from a statically 23 typed language like C#, Java, etc then this 22 might be a surprise: Rails code is not 21 loaded until it is needed. For example, a 20 User model class isn't defined and user.rb isn't loaded 19 until AFTER you try to call User.whatever_method_here. Rails prevents 18 Ruby from complaining about that missing 17 constant, loads code for User, and then allows 16 Ruby to continue as normal.

While I can't 15 speak for your specific need, I would be 14 very surprised if you actually needed to 13 use the require_dependency method from within a plugin or 12 engine. If you follow Rails conventions 11 you shouldn't have to tweak the $LOAD_PATH 10 by hand, either. This is not "the Rails 9 way".

In the world of Ruby and also Rails 8 simplicity and clarity is key. If all you 7 want to do is write a plugin or engine and 6 you are already diving deep into internals 5 then you may consider approaching your problem 4 from a different angle. My gut tells me 3 that you may be trying to do something that 2 is needlessly complicated. But then again, I 1 have no clue what you are doing exactly!! :)

Score: 26

require_dependency is useful in an engine when you want to 4 re-open a class which is not defined in 3 your engine (for example in another engine 2 or Rails app) and have it reloaded. In which 1 case something like this works:

# app/controllers/my_engine/documents_controller.rb
require_dependency MyEngine::Engine.root.join('app', 'controllers', 'my_engine', 'documents_controller').to_s

module MyEngine
  class DocumentsController
    def show
      render :text => 'different'

More Related questions