よく起きる問題
Railsチュートリアルでサンプルアプリケーションを作っていくと、以下のエラーに遭遇する人が結構いるみたいです。
`require': cannot load such file -- active_job/railtie (LoadError)
おそらく同じエラーで困っている方の例
- rails generate rspec:installが実行できない
- rails cannot load such file -- active_job/railtie (LoadError)
- Ruby on Rails チュートリアルで学習中 3章でハマっている
手っ取り早く原因と解決策を知りたい方へ
上のようなエラーはrails new
するときにRails 4.2が実行されたために発生します。
そこでRailsチュートリアルで使われているRailsと同じバージョンが実行されるよう、rails new
コマンドを打ち込むときに必ずバージョンを指定してください。
※注:この記事の執筆時点のRailsチュートリアルでは Rails 4.0.5 が使われています。
第1章 1.2.3最初のアプリケーション
# rails new first_app
# ではなく
$ rails _4.0.5_ new first_app
第2章 2.1 アプリの計画
# rails new demo_app
# ではなく
$ rails _4.0.5_ new demo_app
第3章 ほぼ静的なページの作成
# 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のバージョンを確認できます。
$ 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が起動します。
$ 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が最新になっています。
$ 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のバージョンを確認する場合も注意が必要です。
以下の実行例を見てください。
# ホームディレクトリでバージョンを確認する
$ cd ~
$ rails -v
Rails 4.2.0
# Railsアプリのディレクトリに移動してからバージョンを確認する
$ cd ~/dev/my_app
$ rails -v
Rails 4.1.9
このようにカレントディレクトリの状況によって、rails -v
の実行結果が異なります。
詳しい話は省略しますが、Railsアプリのディレクトリにいる場合はそのアプリで使用しているRailsのバージョンが、それ以外の場合はインストールされているRailsの最新バージョンがそれぞれ表示されます。
このあたりの挙動について詳しく知りたい場合はこちらの記事を参考にしてみてください。
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
の内容が若干変わります。
# オプション無しの場合(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
# 以下省略
# --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へ、困って困ってどうしても先へ進まない場合はスタックオーバーフローへ書き込んでみてください。