Automatic Code Reloading in Rails Console
- rails
- ruby
Isn’t it nice how Rails server automatically reloads your code before each request in the development? Wouldn’t it be
nice if Rails console worked the same way? Sure, you can manually call reload!, but gems like active_reload - or
Rails 3.2 itself - make reloading a near no-op most of the time, so we really don’t have to be so stingy about reloading.
Here’s how you can get IRB to reload your code automatically.
Add the following to an initializer (e.g. config/initializers/irb_reloading.rb, or wherever your project’s
conventions dictate):
# Disables reloading of observers in railties from
# ActionDispatch::Reloader.to_prepare (in railtie.rb)
module ObserverReloadingDisabler
module ClassMethods
def instantiate_observers
# Don't reload on every irb line executed, thanks
end
end
def self.prepended(base)
class << base
prepend ClassMethods unless included_modules.include? ClassMethods
end
end
end
module IRBContextWithReloading
# Overrides the default method to trigger a reload of all files before a line
# is executed in irb (i.e. script/console)
def evaluate(line, line_no)
is_exit_command = %w(quit exit).include?(line.strip)
unless is_exit_command
ActiveRecord::Base.send :prepend, ObserverReloadingDisabler
ActionDispatch::Reloader.prepare!
end
result = super(line, line_no)
unless is_exit_command
ActionDispatch::Reloader.cleanup!
end
result
end
end
if defined?(IRB::Context) && defined?(Rails::Console) && Rails.env.development?
IRB::Context.send :prepend, IRBContextWithReloading
puts '=> IRB code reloading enabled'
end
Now you’re ready to go - your code will be reloaded before IRB evaluates a line, so you can change files and see the
changes immediately, without restarting Rails console or calling reload!.
Additional Notes
-
If you are using a version of the
ruby-debuggem that overridesIRB::Context#evaluate(version 0.10.4 does, other versions might do so as well), you’ll need torequire 'ruby-debug'before the meat of this initializer runs - e.g. as the first line inside theifcheck. -
Not using IRB? This idea shouldn’t be difficult to adapt to Pry, or whatever Ruby shell you might be using.
Updated 3/2015
-
The original version used
reload!(true), which no longer exists in newer versions of Rails 3. The code now usesActionDispatch::Reloaderinstead. -
Switched to
prepend-ing a module instead of re-openingIRB::Context. This should make the code more resilient to patching by other code or gems (i.e. ruby-debug). -
Added an extra module -
ObserverReloadingDisabler- to disable observer reloading. They don’t handle reloading very well. Note that this means changes to observers won’t be reloaded.