Railsチュートリアルでrails newするときはバージョンを指定しよう


## よく起きる問題

Railsチュートリアルでサンプルアプリケーションを作っていくと、以下のエラーに遭遇する人が結構いるみたいです。

```
`require': cannot load such file -- active_job/railtie (LoadError)
```

おそらく同じエラーで困っている方の例

- [rails generate rspec:installが実行できない](http://ja.stackoverflow.com/questions/8215/ruby-on-rails-rails-generate-rspecinstall%E3%81%8C%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84)
- [rails cannot load such file -- active_job/railtie (LoadError)](http://qiita.com/w239yuki/items/a5d47731fb563da29da2)
- [Ruby on Rails チュートリアルで学習中　3章でハマっている](http://elearning.hateblo.jp/entry/2014/12/25/154503)

## 手っ取り早く原因と解決策を知りたい方へ

上のようなエラーは`rails new`するときにRails 4.2が実行されたために発生します。

そこでRailsチュートリアルで使われているRailsと同じバージョンが実行されるよう、`rails new`コマンドを打ち込むときに必ずバージョンを指定してください。

※注：この記事の執筆時点のRailsチュートリアルでは **Rails 4.0.5** が使われています。

http://railstutorial.jp/chapters/beginning?version=4.0#sec-install_rails

### 第1章 1.2.3最初のアプリケーション

http://railstutorial.jp/chapters/beginning?version=4.0#sec-the_first_application

```bash
# rails new first_app
# ではなく
$ rails _4.0.5_ new first_app
```

### 第2章 2.1 アプリの計画

http://railstutorial.jp/chapters/a-demo-app?version=4.0#sec-planning_the_application

```bash
# rails new demo_app
# ではなく
$ rails _4.0.5_ new demo_app
```

### 第3章 ほぼ静的なページの作成

http://railstutorial.jp/chapters/static-pages?version=4.0#top

```bash
# rails new sample_app --skip-test-unit
# ではなく
$ rails _4.0.5_ new sample_app --skip-test-unit
```

## なぜバージョンを指定する必要があるのか？

gemは1つのPCに複数のバージョンをインストールすることができます。
`rails new`を実行したときはデフォルトで最新バージョンのRailsが起動します。
もし、あなたのPCにRails 4.2が入っていると、`rails new`したときはRails 4.0.5ではなく、Rails 4.2が実行されます。
**4.0系と4.2系では生成されるファイルの構成が異なり互換性がないため、Railsチュートリアルを進めていくときに思わぬエラーに遭遇します。**

## インストールされているRailsのバージョンを確認する方法

以下のコマンドでインストールされているRailsのバージョンを確認できます。

```bash
$ gem search ^rails$ -l

*** LOCAL GEMS ***

rails (4.2.0, 4.1.9, 4.1.8, 4.0.5)
```

上の実行例のように、4.2系のRailsが最新バージョンになっている場合は`rails new`したときにRails 4.2が起動します。

```bash
$ rails -v
Rails 4.2.0
```

## Rubyのバージョンが変わるとインストールされているgemも変わる
rbenvやRVMを使ってRubyのバージョンを切り替えると、それぞれのバージョンでインストールされているgemのバージョンも異なります。

下は僕のマシンでRubyのバージョンを切り替えたときの実行例です。
Ruby 2.2.1だとRails 4.2.0が最新ですが、Ruby 2.1.5に変えるとRails 4.1.8が最新になっています。

```bash
$ ruby -v
ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]

$ gem search ^rails$ -l

*** LOCAL GEMS ***

rails (4.2.0, 4.1.9, 4.1.8)

$ rbenv shell 2.1.5 
$ ruby -v              
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin13.0]

$ gem search ^rails$ -l

*** LOCAL GEMS ***

rails (4.1.8, 4.1.7, 4.1.1, 4.1.0)
```

「自分はRails 4.0.5しかインストールしていないからバージョンを指定しなくても大丈夫だ」と思っていても、Rubyのバージョンを切り替えたときには状況が変わっている可能性があります。
こういったgemの挙動に注意しましょう。

## Railsアプリのディレクトリにいるかどうかでrails -vのバージョンが変わる

あとついでにもう一点。
`rails -v`でRailsのバージョンを確認する場合も注意が必要です。

以下の実行例を見てください。

```bash
# ホームディレクトリでバージョンを確認する
$ cd ~
$ rails -v
Rails 4.2.0

# Railsアプリのディレクトリに移動してからバージョンを確認する
$ cd ~/dev/my_app
$ rails -v
Rails 4.1.9
```

このようにカレントディレクトリの状況によって、`rails -v`の実行結果が異なります。

詳しい話は省略しますが、Railsアプリのディレクトリにいる場合はそのアプリで使用しているRailsのバージョンが、それ以外の場合はインストールされているRailsの最新バージョンがそれぞれ表示されます。

このあたりの挙動について詳しく知りたい場合はこちらの記事を参考にしてみてください。

- [binstub について翻訳してみた](http://qiita.com/tanaka51/items/bc22c1c364202d3cce4e)
- [Rails 4.1以降のコンソールコマンドは必ず bin/ を付けなきゃいけないの？](http://qiita.com/jnchito/items/c5a0848144203dce6e26)

## rails newするときに --skip-test-unit オプションを付けるとapplication.rbの内容が変わる

さらにさらに、冒頭に書いた`` `require': cannot load such file -- active_job/railtie (LoadError)``のエラーは、おそらく第3章以降で発生するんじゃないかと思います。

それはなぜかというと、第3章では`rails new`するときに`--skip-test-unit`オプションを付けるからです。

これを付けると`config/application.rb`の内容が若干変わります。

```rb
# オプション無しの場合（Rails 4.2.0）
require File.expand_path('../boot', __FILE__)

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module SampleApp
  class Application < Rails::Application
  # 以下省略
```

```rb
# --skip-test-unit オプションありの場合（Rails 4.2.0）
require File.expand_path('../boot', __FILE__)

# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module SampleApp
  class Application < Rails::Application
  # 省略
```

見比べてもらうとわかりますが、`--skip-test-unit`オプションを付けると`require 'rails/all'`ではなく、個別にフレームワークを`require`するようになります。

`require 'rails/all'`であれば、Railsのバージョンが違っても「Railsにお任せ」できるので無効なフレームワークは読み込まれません。
しかし、個別にフレームワークを`require`する場合には`active_job`のようなバージョンに依存するフレームワークが登場してしまい、バージョンが異なるRailsで起動しようとすると「そんなもんねーよ」とRailsに怒られてしまいます。
つまりそれが `cannot load such file -- active_job/railtie` の意味する内容です。

## まとめ

こういったバージョンの扱いはなかなかややこしいですね。
僕も最初の頃はあまりよくわかっていませんでした。（てか、こんな話、初心者が最初からわかるわけがない）

たぶん困っているのはあなただけではありません。
きっと他の人も同じように困っているので、どんどん情報共有していきましょう。


RubyやRailsで新しく学んだことがあればQiitaへ、困って困ってどうしても先へ進まない場合は[スタックオーバーフロー](http://ja.stackoverflow.com/)へ書き込んでみてください。