There are a lot of ways to launch a Ruby or Rails console: irb , bundle exec irb , bundle console , and rails console are some of the most common. They seem similar, but they each work a little bit differently.

If you don’t know what those differences are, you’ll have some problems. Maybe you won’t be able to get your ActiveRecord models connected to the database. Or you’ll require a file and get the wrong version. Or a library you thought would be avaliable, wasn’t.

How do you make sure you’re using the right console at the right time?

Bundler vs non-Bundler

irb is just a plain Ruby console. It doesn’t care about your Gemfile . It doesn’t load anything but the core Ruby libraries. Anything else you want, you have to require .

If you install a gem using gem install , you can require it inside irb . If you used bundle install , you might be able to require it, depending on where Bundler put it. (Bundler will sometimes put gems outside of Ruby’s gem path, if you run something like bundle install --path or bundle install --deployment ).

Since irb ignores your Gemfile , the versions inside your Gemfile.lock don’t matter. irb will load the newest version of a gem it can find:

~/Source/testapps/consoles[master * ] jweiss $ gem list rails *** LOCAL GEMS *** rails ( 4.2.0.beta2, 4.2.0.beta1, 4.1.5, 4.1.1 ) ~/Source/testapps/consoles jweiss $ cat Gemfile | grep rails gem 'rails' , '4.1.5' ~/Source/testapps/consoles jweiss $ irb irb ( main ) :001:0> require 'rails' => true irb ( main ) :002:0> Rails.version => "4.2.0.beta2"

This can cause really weird problems with your code, if you’re not expecting it.

irb is great if you’re messing with core Ruby files. It’s fast, and doesn’t need any setup.

But if you want to use your Gemfile when you run a console, run bundle exec irb instead. The bundle exec allows irb to load the gems that Bundler knows about, and only the gems Bundler knows about:

~/Source/testapps/consoles jweiss $ bundle exec irb irb ( main ) :001:0> require 'rails' => true irb ( main ) :002:0> Rails.version => "4.1.5"

We got exactly the Rails version we were looking for.

bundler/setup vs Bundler.require

When would you run bundle console instead of bundle exec irb ?

bundle exec irb sets things up so you can only require the gems in your Gemfile.lock .

bundle console goes one step further. When you run bundle console , you don’t even need to require the gems in your Gemfile . They’re already required for you:

~/Source/testapps/consoles jweiss$ bundle exec irb irb(main):001:0> Rails.version NameError: uninitialized constant Rails from (irb):1 from /usr/local/bin/irb:11:in `<main>' ~/Source/testapps/consoles jweiss$ bundle console irb(main):001:0> Rails.version => "4.1.5"

You could also get this behavior if you called Bundler.require inside your bundle exec irb console. Any gem in your Gemfile that isn’t marked require: false will be automatically required, and you’ll be able to use it without any extra work. When you’re working on projects with a Gemfile , that’s incredibly convenient.

Accessing Rails

There’s still one difference to think about: bundle console and rails console .

~/Source/testapps/consoles jweiss $ bundle console irb ( main ) :001:0> Rails.application => nil ~/Source/testapps/consoles jweiss $ rails console Loading development environment ( Rails 4.1.5 ) irb ( main ) :001:0> Rails.application => #<Consoles::Application:0x007f8db4d5ab30 @_all_autoload_paths=["/Users/jweiss...

bundle console just requires a bunch of gems. rails console requires those gems, but it will also load your entire Rails environment, set up autoloading, initialize your application, and give you a full Rails environment to play around in.

You can get something like the Rails console from bundle console if you require config/environment.rb :

~/Source/testapps/consoles jweiss $ bundle console irb ( main ) :001:0> Rails.application => nil irb ( main ) :002:0> require_relative 'config/environment.rb' => true irb ( main ) :003:0> Rails.application => #<Consoles::Application:0x007fd264f0b7c8 @_all_autoload_paths=["/Users/jweiss...

Each one, just a little more complicated

So, to recap:

irb is the basic Ruby console. It ignores your Gemfile , and only core Ruby classes are accessible without require -ing them. It can’t easily load gems that Bundler installs outside of RubyGems’ load path.

bundle exec irb is like irb , if you also required bundler/setup . You can only easily require gems that are in your Gemfile.lock , but you can load those gems no matter where Bundler put them.

bundle console is like bundle exec irb , if you also called Bundler.require . All of the gems in your Gemfile , except the ones marked require: false , can be used without requiring them. It’s really convenient when you’re writing your own gems, or working on non-Rails code.

rails console is like running bundle console inside a Rails app, if you also required config/environment.rb . You can play with your entire Rails app, autoloads and database connections work, and everything’s hooked up the way you’d expect. If you’re working in a Rails app, this is the most helpful kind of console.

There aren’t too many differences between these consoles. And while most of those differences won’t be too big (Oh, this file isn’t required? Better require it!), others will be totally infuriating if you don’t know what’s going on. (WHY IS THIS LOADING THE WRONG VERSION OF RAKE AGAIN!?)

But if you know the idea behind each of these consoles, you’ll be able to use the right kind of console at the right time. And all the libraries you need will be close by when you need them.