【Ruby on Rails】The `rails' command exists in these Ruby versions エラーの解決方法

【Ruby on Rails】The `rails' command exists in these Ruby versions エラーの解決方法

8分で読めるテック
最終更新:

rbenvでRubyのバージョンを切り替えた直後、rails --version を実行したら次のエラーが出ました。

The `rails' command exists in these Ruby versions:
  2.x.x

「railsはインストールしたはずなのに使えない」という状況です。当時の環境はRuby 2.5.1 / Rails 6.0.0で、手順自体は現行バージョンでも同様に動作します。結論から言うと、gem install rails を現在のバージョン向けに実行し直すだけで解決します。

なぜこのエラーが起きるのか

rbenvやrvmはRubyのバージョンを切り替える仕組みですが、gemはRubyのバージョンごとに独立して管理されています。あるバージョンにインストールしたgemは、別のバージョンからは参照できません。

つまりエラーメッセージの意味は「railsコマンドは別のRubyバージョンには存在するが、今使っているバージョンにはインストールされていない」ということです。バージョンを切り替えたタイミングで、新しいバージョン向けのgemが存在しない状態になっています。

gemがバージョンごとに独立している理由

RubyのC拡張を含むgemは、Rubyのバージョンに依存したネイティブコードをコンパイルして生成します。あるバージョン向けにビルドしたバイナリは別バージョンのRubyでは動きません。純粋なRubyコードだけのgemであっても、rbenvはgemのパスを ~/.rbenv/versions/<version>/lib/ruby/gems/ 以下にバージョン別で管理するため、他バージョンのgem置き場は参照されません。

rbenvでの実際のパス構造を確認するとこうなります。

$ rbenv which gem
/Users/yourname/.rbenv/versions/3.2.0/bin/gem

$ gem env home
/Users/yourname/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0

バージョンを切り替えると rbenv which gem の出力が変わり、別のディレクトリを参照するようになります。前のバージョンでインストールしたgemはそのまま別パスに残っているため、gem list を旧バージョンで確認すると今まで入れたgemが見えますが、新バージョンに切り替えると全て消えたように見えます。

解決手順

現在使用しているRubyバージョンにrailsを再インストールします。

$ gem install rails

インストール完了後、コマンドが使えるか確認します。

$ rails --version
Rails 6.0.0

rbenvを使っている場合、gemのインストール後に rbenv rehash が必要なこともあります。シェルがコマンドのパスを更新するためのコマンドです。

$ rbenv rehash

Bundlerを使ったプロジェクトに入る場合は、あわせて bundle install も実行しておくとよいです。プロジェクトが依存するgemを新しいRubyバージョン向けに揃えられます。

rbenv rehash が必要な理由

rbenvはシェルに rbenv shims のディレクトリをPATHに追加することで動作します。rails コマンドは実際には shims ディレクトリ内の小さなラッパースクリプトであり、呼び出し時に現在のRubyバージョンに対応する本物の rails を見つけて実行します。

新しいgemをインストールしても、この shims が自動で更新されないケースがあります。rbenv rehash を実行すると ~/.rbenv/shims/ ディレクトリが再生成され、インストールしたgemのコマンドが正しく参照されるようになります。

# shims の中身を確認する
ls ~/.rbenv/shims/ | grep rails
# => rails(存在しなければ rehash が必要)

現行バージョンのrbenvでは gem インストール後に自動で rehash が走るよう改善されているケースもありますが、動かない場合は手動で実行するとよいです。

バンドラー(Bundler)との関係

プロジェクトに Gemfile がある場合、単に gem install rails でグローバルにインストールするよりも bundle install でプロジェクト内の依存を揃える方が推奨されます。

# プロジェクトディレクトリで
$ bundle install

# bundle exec 経由でコマンドを実行する
$ bundle exec rails --version

bundle exec をつけると Gemfile.lock に記載されたバージョンのgemが優先して使われます。グローバルにインストールした別バージョンのrailsとの混在を防げます。

Gemfile.lock にはgemのバージョンだけでなく、RUBY VERSION として動作確認済みのRubyバージョンも記録されます。バージョン切り替え後にこのエントリが現在のバージョンと合わない場合は bundle update --ruby で更新できます(バージョンによって挙動が異なるため確認してから実行してください)。

同種のエラーへの応用

このエラーを理解すると、同じ原因で起きる類似エラーに対処できます。

  • The 'rake' command exists in these Ruby versions: gem install rake で対応
  • The 'bundler' command exists in these Ruby versions: gem install bundler で対応
  • rspecpuma など他のコマンドでも同様

バージョン切り替え直後に複数のコマンドが使えなくなった場合、まず gem list で現在のバージョン向けにどのgemが入っているか確認するとよいです。

$ gem list
# 何も(または少ししか)入っていなければ、新バージョン向けの gem が未インストール

よく使うgemをまとめてインストールしたい場合は、以下のようにまとめて実行できます。

$ gem install rails bundler rubocop
$ rbenv rehash

また .ruby-version ファイルをプロジェクトルートに置いておくと、そのディレクトリに入った時点でrbenvが自動的に指定バージョンに切り替えます。バージョン管理を明示的にしておくと、チーム開発やCI環境でのバージョン不一致を防ぎやすくなります。

# プロジェクトルートに .ruby-version を作成
$ echo "3.2.0" > .ruby-version

# そのディレクトリに入ると自動でバージョンが切り替わる
$ ruby --version
ruby 3.2.0 ...

参考ドキュメント

rbenvの詳細なコマンドリファレンス(バージョン切り替え・shims・rehashの仕組みなど)は公式リポジトリを参照してください。

gemのインストールと管理の基本(gem install / gem list / gem uninstall の動作)はRubyGemsの公式ガイドにまとまっています。

BundlerとGemfile、bundle install / bundle exec の使い方はBundlerの公式ドキュメントを参照してください。

質問・リクエストを送る

記事についての質問や、取り上げてほしいテーマがあればお気軽にどうぞ。いただいた質問はブログ記事として回答し、Q&Aページで公開することがあります。

このサイトについて

井上 周(Amane Inoue)の個人ブログです。技術・読書・ドラマ・旅・大学生活のことを書いています。