- 更新日: 2014年6月17日
- Rails
Rails と Ruby のアップデート作業手順
Mac のローカルの開発環境で、Ruby と Rails のバージョンをアップデートしたのでその作業の備忘録です。まずトラブルがリカバーできない時のために、ブランチを切ってそっちでアップデートの作業を行う。
Ruby 2.0.0 → 2.1.2
Rails 4.0.1 → 4.1.1
それぞれ、以上のバージョンへとアップデートしました。先に書いておきますが、テストを書いていない場合はアップデート作業はかなり苦痛が伴うはずです。テストを書いていないプロジェクトの場合は、アップデートの前にテストを書いておくことをお勧めします。
長くなったので目次。
— 目次 —
・Ruby のバージョンをアップデート
・Bundler と Passenger をインストール
・Rails のバージョンをアップデート
・RSpec のテストを実行しアプリケーションが正常に動作するか確認
・起こったエラー1: 使ってないはずの minitest の Warning
・起こったエラー2: Nokogiri の constant がない
・起こったエラー3: select + count で Mysql2::Error
・起こったエラー4: Digest::Digest is deprecated
では作業へ。まず、アップデート作業用の Git ブランチを切る。
1 2 3 |
$ git checkout -b ruby-rails-version-update |
おそらくトラブルが少ないであろう、Ruby 自体のアップデートから行いました。
Ruby のバージョンをアップデート
Rubyを 2.0.0 から最新安定バージョンの 2.1.2 へとアップデートします。homebrew で rbenv と ruby-build を upgrade。
1 2 3 4 5 |
$ brew update $ brew upgrade rbenv $ brew upgrade ruby-build |
インストール可能な Ruby のバージョンの確認。
1 2 3 |
$ rbenv install -l |
CONFIGURE_OPTS を付与して、最新の Ruby 2.1.2 をインストールして rehash。
1 2 3 4 |
$ CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-iconv-dir=`brew --prefix libiconv`" rbenv install 2.1.2 $ rbenv rehash |
CONFIGURE_OPTS を付けとかないと、irb で日本語文字化けが起こるためなどが理由です。
rbenv 環境の Ruby の irb で日本語が文字化けするので直した | EasyRamble
インストール済みの Ruby を確認。
1 2 3 |
$ rbenv versions |
最新の Ruby 2.1.2 へと変更。
1 2 3 4 |
$ rbenv global 2.1.2 $ rbenv rehash |
Bundler と Passenger をインストール
Ruby 2.1.2 環境に Bundler と Passenger をインストールします。Apache + Passenger を使わない場合は、Passenger のインストールは不要です。
bundler インストール。
1 2 3 4 |
$ gem install bundler $ rbenv rehash |
Passenger インストール。
1 2 3 4 |
$ gem install passenger $ rbenv rehash |
続いて、Passenger の Apache 用モジュールをインストールします。
1 2 3 |
$ passenger-install-apache2-module |
LoadModule のスニペットを Apache の設定ファイルとして、passenger.conf に追加。詳しくは、以下の Passenger のインストールを参照。
Ruby on Rails の環境を構築し Redmine をインストール 〜 CentOS6 | EasyRamble
以上で、Ruby と Rails を動かすための環境は整いました。その他、バーチャルホストや DocumentRoot などウェブサーバー側の設定も必要に応じて。以前と変更なしなら、必要ないです。
以上で Ruby のアップデートは終了なので、この辺りでテスト実行して通るかどうかを確認しておきます。続いて Rails のアップデートです。
Rails のバージョンをアップデート
Rails を 4.0.1 から最新安定バージョンの 4.1.1 へとアップデートします。
Rails プロジェクトのルートディレクトリへと移動。
1 2 3 |
$ cd /path/to/rails_root |
Gemfile を更新。
1 2 3 4 5 |
$ vi Gemfile # gem "rails", "4.0.1" gem "rails", "4.1.1" |
Gemfile.lock を更新して、Ruby 2.1.2 環境用に gem をインストール。
1 2 3 4 |
$ bundle update $ bundle install |
続いて、rake コマンドで Rails を update。設定ファイル等を更新するためであり、conflict したファイルを上書きするかどうか聞かれます。なので、conflict したファイルは d を押して diff(差分)を確認して上書きするかどうか決めていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ bundle exec rake rails:update conflict config/boot.rb Overwrite /Users/username/path/to/rails_project/config/boot.rb? (enter "h" for help) [Ynaqdh] d # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) - require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) + require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) Retrying... Overwrite /Users/username/path/to/rails_project/config/boot.rb? (enter "h" for help) [Ynaqdh] Y force config/boot.rb exist config conflict config/routes.rb Overwrite /Users/username/path/to/rails_project/config/routes.rb? (enter "h" for help) [Ynaqdh] d ... Retrying... Overwrite /Users/username/path/to/rails_project/config/routes.rb? (enter "h" for help) [Ynaqdh] n skip config/routes.rb |
こんな感じです、上の手順では config/boot.rb は上書きして、config/routes.rb は上書きしない、と進めています。以降も同じように d(diff)で差分を見ながら、上書きするかどうか決定していく。今回私の環境では、以下の通りで進めました。
config/boot.rb
上書きする
config/routes.rb
上書きしない
config/application.rb
上書きしない
config/environment.rb
上書きしない
config/environments/development.rb
上書きしない
config/environments/production.rb
上書きしない
config/environments/test.rb
上書きしない
config/initializers/mime_types.rb
上書きする
config/initializers/session_store.rb
上書きしない
config/locales/en.yml
上書きしない
基本的に、変更の必要ないファイルは n(上書きしない)にしておいて、変更が必要そうなファイルは Y(上書きする)にしました。4.0.1 → 4.1.1 へのアップデートのためか、設定ファイルが変わっている箇所は少ない印象。そのため上書きしないで済むファイルのほうが多かったです。上書きしたファイルについては、diff を見て手動で設定を書きなおす必要があります。
RSpec のテストを実行しアプリケーションが正常に動作するか確認
ここまでを終えたら、RSpec テストを実行して Rails 4.1.1 の環境でも正しくテストが通るかを確認します。おそらく、一発でオールグリーンは難しいかと思います。
1 2 3 |
$ bundle exec rspec spec/ |
以降は、Ruby 2.1.2 + Rails 4.1.1 のアップデート後の環境で、テスト実行で明らかになったエラー箇所とその解決策です。
起こったエラー1: 使ってないはずの minitest の Warning
最初に試しにテストを走らせてみました。
1 2 3 4 5 |
$ bundle exec rspec spec/controllers/application_controller_spec.rb Warning: you should require 'minitest/autorun' instead. Warning: or add 'gem "minitest"' before 'require "minitest/autorun"' |
使ってない minitest でのエラー、なんだこれ…。ということで、以下などを参考にして…
https://github.com/thoughtbot/shoulda-matchers/issues/408
spec/spec_helper.rb
1 2 3 |
require 'minitest' |
を追加したところ、Warning が消えました。
起こったエラー2: Nokogiri の constant がない
Nokogiri の autoload が効かなくなっているみたいでした。自作モジュール内で使っていた Nokogiri で以下のエラー発生。
1 2 3 |
uninitialized constant Hoge::Nokogiri |
解決策は、Gemfile に nokogiri を追加。
Gemfile
1 |
gem 'nokogiri' |
1 2 3 |
$ bundle install |
これで解決。Gemfile に宣言すると、おそらく Nokogiri が自動ロードされる gem に指定される…のかな?(あまり自信ないです)
起こったエラー3: select + count で Mysql2::Error
以下のフォーラムで話題になっているのと同じエラーに遭遇しました。
Relation count returns syntax error in Rails 4.1.X – Ruby Forum
一言で言うと、Rails の ActiveRecord の API を利用して、select で2つ以上のカラムを指定する + count を同時に使うと SQL シンタックスがエラーになる。以下の例の通りです。
1 2 3 4 5 |
pry(main)> User.select(:id, :name).count (21.3ms) SELECT COUNT(id, name) FROM `users` Mysql2::Error: |
1 2 3 4 5 |
pry(main)> User.select(:name).count (4.0ms) SELECT COUNT(`users`.`name`) FROM `users` => 10 |
select のカラム指定が1つであればOKです。また、count メソッドを count(:all) に変更すると従来通りの動作になります。
1 2 3 4 5 |
User.select(:id, :name).count(:all) (3.0ms) SELECT COUNT(*) FROM `users` => 104 |
なので解決策としては、count → count(:all) に変更のリファクタリングを行いました。
起こったエラー4: Digest::Digest is deprecated
厳密にはエラーではないですが、以下の deprecated の警告が発生しました。
1 2 3 |
Digest::Digest is deprecated; use Digest |
OpenSSL 関連が理由らしく use Digest と指示が出ています。テストで、OpenSSL::Digest::Digest を使っている gem を突き止めて、新しいバージョンの gem にアップデートします。
私の環境では、flickraw が原因でした。flickraw は Flickr API のラッパー gem です。flickraw を最新にするため、Gemfile のバージョン指定を外しました。
Gemfile
1 2 |
# gem "flickraw", "0.9.7" gem "flickraw" |
1 2 3 4 |
$ bundle update $ bundle install |
これで flickraw が 0.9.8 になり Digest::Digest is deprecated のエラー消滅。
以上のエラー解決により、テストがオールグリーンとなりました!ばんざ〜い!最後に master ブランチにマージ。
1 2 3 4 |
$ git checkout master $ git merge ruby-rails-version-update |
以上で、アップデートの作業は終了です。
とりあえず RSpec のテストをしっかり書いていたので、エラー検出とその対策はそれほどはまることなく進められました。ブラウザでの手動テストでも問題なく動作しています。
もしテストを書いてなかったら、ちょっと Rails アプリケーションのバージョンアップは不可能に思えます。しかし、自信を持てる程度のテストを書けているプロジェクトであれば、Rails と Ruby のアップデートはそれほど大変でもないかな〜というのが、今回のアップデート作業での感想です。はまったら大変なのでしょうけどね…。機会があれば(自己責任で)トライされてみてください!
- – 参考リンク –
- Ruby on Rails 4.1 Release Notes — Ruby on Rails Guides
- Ruby on Rails 4.1 Release Notes #6(Active Record) – rochefort’s blog
- warnings – Ruby – Digest::Digest is deprecated; Use Digest – Stack Overflow
- Rails 4.0.4を4.1.0にアップグレードした – 平凡なエンジニアの独り言
- 妻のパン屋のwebサイトをいろいろ更新した話 ~Rails 4アップデートとかサイトの高速化とか~ – give IT a try
- Rails の関連記事
- RailsでMySQLパーティショニングのマイグレーション
- Rails ActiveRecordでdatetime型カラムのGROUP BY集計にタイムゾーンを考慮する
- RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方
- RailsでAMPに対応するgemをリリースしました
- Railsでrequest.urlとrequest.original_urlの違い
- Railsでwheneverによるcronバッチ処理
- Google AnalyticsのRails Turbolinks対応
- Railsアプリにソーシャル・シェアボタンを簡単設置
- Rails監視ツール用にErrbitをHerokuで運用
- Facebook APIバージョンのアップグレード手順(Rails OmniAuth)
- 2件のコメント
インストール済みのRubyを確認後、
$ rbenv global 2.2.2
$rbenv rehash
を入力してもTerminalでは前バージョンとなってしまいます。どうすれば、良いでしょうか?
匿名希望さん、こんにちは!コメントありがとうございます。
ちょっと詳細がよく分かりませんが、以下のように ruby コマンドで確認すると以前のバージョンになる、ということでしょうか?
$ ruby -v
前バージョンの ruby
この前提で話を進めますが、まず以下のコマンドで、読み込まれている ruby のパスを確認して下さい。
$ which ruby
/Users/ユーザー名/.rbenv/shims/ruby
これが、/Users/ユーザー名/.rbenv/shims/ruby ではない場合、システムのデフォルトの ruby が呼ばれているかもしれません。その原因は、おそらく環境変数(PATH)を設定ミスのせいかと思われます。
/Users/ユーザー名/.rbenv/shims/ のパスを環境変数(PATH)の先頭に追加してください。以下公式のドキュメントに詳しく書いてあります。
https://github.com/sstephenson/rbenv
解決できなかったら、もう1回コメントくださいね!