[Ruby on Rails 4] Rails 4.2, Ruby 2.4 で動いているアプリのパッチバージョンをアップグレードする

完全に閉じた環境で利用していたので後回しにしていた Rails 4.2 アプリを3周遅れくらいでバージョンアップしていきます。

教本はこちら。いつもありがとうございます。

まずはそれぞれのパッチバージョンを上げていきます。

rails 以外の gem のバージョンを確認する

  • Rails 4.2.11

アップグレード用の git branch を作成します。
Gemfile を編集していきます。

% git checkout -b rails-4-2-11-1-migration

gem outdated でバージョンを確認します。
Rails 4 のサポートが終わっている gem にはバージョン指定とコメントを追加しておきます。

% bundle outdated | bof --format markdown
  • Rails のバージョンは固定しておきます。
  • トラブることが多い rmagick 等のバージョンも固定しておきます。

あわせてこちらを参考に不要になっている gem を削除しました。

bundle update を実行する

developmentとtestグループのgemを先にアップデートします。

% bundle update -g development -g test

テストをパスすることを確認します。

% bundle exec rspec 

本番環境もアップデートします。

% bundle update

本番環境でテストを実行すると、WARNING が発生しました。

% bundle exec rspec
WARNING: Nokogiri was built against LibXML version 2.9.10, but has dynamically loaded 2.9.4
audited 5 packages in 1.328s
found 0 vulnerabilities


An error occurred while loading ./spec/controllers/delivery_charges_controller_spec.rb.
Failure/Error: ActiveRecord::Migration.maintain_test_schema!

NoMethodError:
  Cannot load `Rails.application.database_configuration`:
  undefined method `[]' for nil:NilClass
    :

mysql2 でうまく接続できていないようです。
また、なぜか database.yml の erb が展開されなくなっています。
rails c からは見えているし、ターミナルから mysql に接続できます。

ひとまず nokogiri の再インストールや Xcode のインストール等、いつものチェックをゴチャゴチャと実行します。
また mac を再起動しました。

% gem uninstall nokogiri
% gem install nokogiri -- --use-system-libraries
% bundle config build.nokogiri --use-system-libraries
% bundle install

Ruby のパッチバージョンを上げる

再起動後、.ruby-version であらかじめインストールしておいたバージョンにアップし試してみます。

  • Ruby 2.4.5 -> 2.4.9

mysql2 と rmagick の bundle install が失敗しました。

% bundle _1.17.3_ install
    :
An error occurred while installing mysql2 (0.4.10), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.4.10' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

こちらを参考に mysql2 のインストールが完了することを確認しましたが問題ないようです。

% gem install mysql2 -v '0.4.10' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib

あらためて bundle の方をアンインストールしておきます。

% bundle exec gem uninstall mysql2

bundle config でオプション追加し、bundle install を実行します。

%  bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include" "--with-ldflags=-L/usr/local/opt/openssl/lib"

rmagick の bundle install が失敗します。

% bundle _1.17.3_ install
    :
An error occurred while installing rmagick (2.16.0), and Bundler cannot continue.
Make sure that `gem install rmagick -v '2.16.0' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  rmagick

これはいつものヤツな気がするので imagemagick をチェックします。

% convert --version

同じく一度アンインストールしておきます。

% bundle exec gem uninstall rmagick

bundle install を実行します。

% PKG_CONFIG_PATH=/usr/local/opt/imagemagick@6/lib/pkgconfig bundle _1.17.3_ install

Cannot load Rails.application.database_configuration エラーの解決

やはりこれが残ったので解決方法を探ります。

% bundle exec rspec
audited 5 packages in 1.303s
found 0 vulnerabilities


An error occurred while loading ./spec/controllers/delivery_charges_controller_spec.rb.
Failure/Error: ActiveRecord::Migration.maintain_test_schema!

NoMethodError:
  Cannot load `Rails.application.database_configuration`:
  undefined method `database' for nil:NilClass
    :

この database.yml 内の erb の展開の仕方が変わっていました。
settings.local.yml を読まなくなっていて、settings.yml に用意すると想定通りに動くようです。

database.yml
default: &default
  adapter: mysql2
  username: <%= Settings.database[:user_name] %>
  password: <%= Settings.database[:password] %>
    :

以前に下記のように対応をしているので、rubyconfig/config を確認します。

git で管理されている config/database.yml にパスワードが書かれているので、config/settings.local.yml に情報を移し、そこから読み込むように変更する。

Rails で MySQL を利用する設定 | deadwood

rails c からは取得できます…。

% bin/rails c
audited 5 packages in 1.064s
found 0 vulnerabilities

Loading development environment (Rails 4.2.11)
[1] pry(main)> Settings.database[:user_name]
=> "hogehoge"

下記のとおり、config/settings.local.yml が優先されるはずが振る舞いが変わっているようにみえます。

Accessing the Settings object After installing the gem, Settings object will become available globally and by default will be compiled from the files listed below. Settings defined in files that are lower in the list override settings higher.

rubyconfig/config: Easiest way to add multi-environment yaml settings to Rails, Sinatra, Pandrino and other Ruby projects.

以下を試した所、想定通りに戻りました。

  • config/settings.local.yml を削除。
  • config/settings/ 以下に test.local.yaml, development.local.yml, production.local.yml をそれぞれ用意。

テストを実行して無事パスしました。

% bundle exec rake db:seed RAILS_ENV=test
% bundle exec rspec

Pending としていた gem のバージョンを上げる

bundle outdated で再度確認します。

% bundle _1.17.3_ outdated | bof --format markdown

Gemfile を調整して bundle update します。

% bundle _1.17.3_ update

Rails のパッチバージョンを上げる

  • Rails 4.2.11 -> 4.2.11.1

最新バージョンを確認して Gemfile の Rails バージョンを変更します。

% bundle _1.17.3_ update

テストを実行。パスして終了です。

% bundle exec rspec

差分をチェックする

最後に RailsDiff を参考にファイルの差分を修正し、テストをパスしました。

つづく。