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-debug
gem 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 theif
check. -
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::Reloader
instead. -
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.