Rails Magic 2: Bundler & The Gemfile

After creating your new app with “rails new my_app”, the next step is to change directories into your my_app directory and run “bundle install”.

cd my_app

bundle install

Again, we get a ton of output from a simple command:

Using rake 10.4.2
Using i18n 0.7.0
Using json 1.8.2
Using minitest 5.5.1
Using thread_safe 0.3.4
Using tzinfo 1.2.2

etc.

More Rails magic?

Well, kind of. This time most of the magic is coming from a gem called Bundler.

I wasn’t around during the dark ages of Rails development, but I presume that before Bundler came along, Rails developers had to venture out with spear in hand, and hunt down each individual gem their app depended on, and then each gem that those gems depended on.

When you run “bundle install” you’re telling Bundler:

  • Look in the file named Gemfile
  • Go to the RubyGems API (or whichever source is declared at the top of the Gemfile).
  • Find all the gems listed in the Gemfile plus all the gems that those gems depend on.
  • If the gem is already installed, use that. If not, install it.
  • Take a snapshot of the full gem list and store it in Gemfile.lock
  • Add the gems to the load path, making them available to every file in the app. (This saves you the step of having to specifically require each gem in any file that will need it).

Never make changes to Gemfile.lock. That file is for Bundler’s use only.

The problem with editing Gemfile.lock directly is that it will be overwritten the next time you run “bundle install”. Instead, add new gems to Gemfile and run “bundle install”. Bundler will take care of updating Gemfile.lock.

Go ahead and take a look at the default Gemfile and Gemfile.lock that are created when you run “rails new”. See how many more lines are in Gemfile.lock? That will give you an idea of just how much work Bundler does for you.

Rails Magic: Creating an App

The first place a new developer encounters Rails Magic is in creating a new app.

It’s an incredibly simple command, with a dizzying amount of action behind it.

Assuming you have Ruby and Rails installed, you need only open a terminal window and type:

rails new blog_app

BAM! Rails app created.

You now have a massive “blog_app” directory full of files, 100 lines of command line output, and no clue what just happened.

How did the app get created?

Do you really need 40+ files for a simple blog app?

To understand how your Rails app was created, it’s helpful to look at the slow way of doing the same thing:

The Slow Way

1. Make a directory for your app and change into that directory

mkdir my_app

cd my_app

2. Create a subdirectory for each of the subfolders

mkdir app

mkdir config

etc.

3. Create the files that go inside the subdirectories, as well as the free-standing files that are not contained in a subdirectory

touch Gemfile (not inside a subdirectory)

touch routes.rb (not inside a subdirectory)

touch config/environments/development.rb (this file is inside the config/environments subdirectory)

etc.

4. Open each of those files and set some basic configuration settings, such as which database will be used and which gems (packages of pre-written code) will be included.

“Rails new” creates 40+ subdirectories and files, so doing this manually would take quite a while.

However, many of the files that it creates are only used in highly complex apps, and if it wasn’t so much easier to type “rails new”, you would probably create just a fraction of the files that are automatically created.

In the blog post Minimal Rails, Scott Raymond shows how you can create a Rails app with just 6 subdirectories: app, app/controllers, config, config/environments, log and public. It’s a great exercise for understanding the basic Rails framework.

Most apps will use more than the 6 subdirectories listed in Minimal Rails, but less than the “Rails new” command generates.

We’ll look into what each of those subdirectories does in a future post.

Rails Magic

By far the most frustrating part of learning Ruby on Rails was the confusion of dealing with “Rails Magic”. I remember telling someone, “I love Ruby, but I hate Rails. There’s no logic to the things it does.”

It’s a lot like looking at a solution to a complex math problem solved by a mathematician who doesn’t bother writing out the steps she can do in her head.

An experienced mathematician will appreciate not having to write out or read those basic steps, but if someone were to try to learn math by following that example, she would be hopelessly lost.

There are a ton of things in Rails that are helpful shortcuts for experienced Rails developers, but are tremendously confusing for newbies.

For example, there is a seemingly endless number of ways to tell Rails:

If the URL is ‘www.example.com/photos/new’, you should show the template located in the file ‘photos/new.html.erb’

Amongst those endless options, the ones that are most commonly used are the ones that give you the least information about what they are doing behind the scenes.

This is true not just for routes, but for pretty much every part of Rails. It’s chock full of short-cuts and assumptions, and if you don’t know what those short-cuts and assumptions are, it can be quite difficult to understand.

For that reason, I have decided to write a series that will connect the dots between the explicit or long way of doing things and the more commonly-used shortcuts.

Coming up: Part 1: Creating an App