LoginSignup
7
3

More than 5 years have passed since last update.

Ruby 2.2.3 で動いている Rails アプリケーションを Ruby 2.6.2 にアップデートした話

Posted at

Ruby 2.2.3 で動いている Rails アプリケーションの Ruby バージョンを 2.6.2 まで上げました。対応の多くがアプリケーションが依存する gem によってしまうので、全ての対応が適用できる訳ではありませんが、少しでも参考になれば幸いです。

背景

Ruby 2.2 は2018年3月31日をもってサポートが終了しています。

しかし、対象となったアプリケーションはテストコードが書かれておらず、バージョンアップを行なってもアプリケーションの動作担保が難しい状態でした。

一方で、機能開発を止めることも難しかったため、機能追加を行うたびにテストコードを少しずつ増やしてきました。そして、ようやく最低限のテストコードが揃ったと判断し、今回の Ruby のバージョンアップに踏み切りました。

TL;DR

ruby と、依存する 最低限の gem 10個をアップデートしました。

  • ruby を 2.2.3 -> 2.6.2 にアップデート
  • delayed_job を 4.1.2 -> 4.1.5 にアップデート
  • fog を 1.33.0 -> 1.41.0 にアップデート
  • therubyracer を 0.12.2 -> 0.12.3 にアップデート
  • rails を 4.2.6 -> 4.2.11.1 にアップデート
  • sass-rails を 5.0.4 -> 5.0.7 にアップデート
  • activerecord-session_store を 0.1.1 -> 1.1.3 にアップデート
  • devise を 3.5.10 -> 4.6.2 にアップデート
  • devise_invitable を 1.5.5 -> 1.7.5 にアップデート
  • capistrano を 3.4.0 -> 3.11.0 にアップデート
  • rubocop を 0.60.0 -> 0.62.0 にアップデート

rails server を立ち上げる

まずはローカル環境で rails server が立ち上げることを目指します。以下、発生したエラーとその原因、対応です。

delayed_job

ERROR メッセージ

Bundler::GemRequireError: There was an error while trying to load the gem 'delayed_job_active_record'.
Gem Load Error is: undefined method `yaml_as' for ActiveRecord::Base:Class

原因

対応

fog

ERROR メッセージ

LoadError: cannot load such file -- xmlrpc/client
<略>
  /Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/fog-1.33.0/lib/fog/xenserver/core.rb:23:in `<class:Connection>'
  /Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/fog-1.33.0/lib/fog/xenserver/core.rb:22:in `<module:XenServer>'
  /Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/fog-1.33.0/lib/fog/xenserver/core.rb:5:in `<module:Fog>'
  /Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/fog-1.33.0/lib/fog/xenserver/core.rb:4:in `<top (required)>'

原因

対応

therubyracer

ERROR メッセージ

Bundler::GemRequireError: There was an error while trying to load the gem 'therubyracer'.
Gem Load Error is: wrong argument type Class (expected Module)

原因

対応

rails

ERROR メッセージ

SystemStackError: stack level too deep
  /root/repo/vendor/bundle/ruby/2.6.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/conversions.rb:131:in `block (2 levels) in <class:Numeric>'

原因

対応

簡単な動作を確認をする

ここまでで rails server が立ち上がりました :raised_hands: 動作を確認しながら WARN/ERROR メッセージに対応していきます。

sass-rails

WARN メッセージ

DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /root/repo/vendor/bundle/ruby/2.6.0/gems/sass-rails-5.0.4/lib/sass/rails/railtie.rb:57)
DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /root/repo/vendor/bundle/ruby/2.6.0/gems/sass-rails-5.0.4/lib/sass/rails/railtie.rb:58)
no_proxy is unsupported

原因

対応

bundle update は完了するが、以下のメッセージが表示される。

Ruby Sass is deprecated and will be unmaintained as of 26 March 2019.

sass-rails のメンテナンスが2019年3月26日をもって終了した。今後は、sass/sassc-ruby: Use libsass with Ruby! を利用することが推奨されている。今回の修正範囲外とするが早めに対応したい。

See also: Ruby Sass Has Reached End-Of-Life « Sass Blog

activerecord-session_store

ERROR メッセージ

Thread.exclusive is deprecated, use Thread::Mutex
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/activerecord-session_store-0.1.1/lib/active_record/session_store/session.rb:32:in `find_by_session_id'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/activerecord-session_store-0.1.1/lib/action_dispatch/session/active_record_store.rb:66:in `block in get_session'

原因

対応

devise

ERROR メッセージ

SyntaxError - syntax error, unexpected '{', expecting keyword_end
...ter only: [:create, :destroy] { request.env["devise.skip_tim...
...                              ^
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/devise-3.5.10/app/controllers/devise/sessions_controller.rb:5: syntax error, unexpected '}', expecting keyword_end
..."devise.skip_timeout"] = true }
...                              ^:
  devise (3.5.10) app/controllers/devise/sessions_controller.rb:5:in `'

undefined method `unshift' for nil:NilClass excluded from capture: No host specified, no public_key specified, no project_id specified

NoMethodError (undefined method `unshift' for nil:NilClass):

原因

対応

ERROR メッセージ

NoMethodError - undefined method `for' for #<Devise::ParameterSanitizer:0x00007fc999e94890>:
undefined method `user_omniauth_authorize_path' for #<#<Class:0x00007ffa5913a5c8>:0x00007ffa58bae348>

原因

対応

- devise_parameter_sanitizer.for(:sign_up)
- devise_parameter_sanitizer.for(:sign_in)
+ devise_parameter_sanitizer.permit(:sign_up)
+ devise_parameter_sanitizer.permit(:sign_in)
- user_omniauth_authorize_path(:facebook)
+ user_facebook_omniauth_authorize_path

devise_invitable

ERROR メッセージ

Traceback (most recent call last):
bin/rails: undefined method `attributes_for' for class `Devise::ParameterSanitizer' (NameError)

原因

対応

Rspec や Rubocop などを動かす

ここまででローカル環境での動作確認ができました :raised_hands: ここから Rspec や Rubocop などを動かしていきます。

rubocop

ERROR メッセージ

$ bundle exec rubocop
unknown keywords: whitelist_classes, whitelist_symbols
/Users/tetsuya/.rbenv/versions/2.6.2/lib/ruby/2.6.0/psych.rb:328:in `safe_load'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/lib/rubocop/config_loader.rb:185:in `yaml_safe_load'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/lib/rubocop/config_loader.rb:159:in `load_yaml_configuration'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/lib/rubocop/config_loader.rb:40:in `load_file'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/lib/rubocop/config_loader.rb:82:in `configuration_from_file'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/lib/rubocop/config_store.rb:44:in `for'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/lib/rubocop/cli.rb:187:in `apply_default_formatter'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/lib/rubocop/cli.rb:40:in `run'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/exe/rubocop:13:in `block in <top (required)>'
/Users/tetsuya/.rbenv/versions/2.6.2/lib/ruby/2.6.0/benchmark.rb:308:in `realtime'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/rubocop-0.60.0/exe/rubocop:12:in `<top (required)>'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/bin/rubocop:23:in `load'
/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/bin/rubocop:23:in `<top (required)>'

原因

  • 元を辿ると DHH の black/whitelist って呼び方はよくないんじゃないかという発言に起因する

対応

rubocop-github

ERROR メッセージ

Error: The `Performance/LstripRstrip` cop has been moved to `Style/Strip`
(obsolete configuration found in vendor/bundle/ruby/2.6.0/gems/rubocop-github-0.12.0/config/default.yml, please update it)

原因

対応

検証環境に deploy する

CI も通ったので検証環境に deploy 試みます。

sshkit

ERROR メッセージ

/Users/tetsuya/dev/app_name/vendor/bundle/ruby/2.6.0/gems/sshkit-1.7.1/lib/sshkit/runners/parallel.rb:16:in `rescue in block (2 levels) in execute': Exception while executing as devuser@52.197.98.157: undefined method `<' for nil:NilClass (SSHKit::Runner::ExecuteError)

原因

--

対応

capistrano

WARN メッセージ

[Deprecation Notice] Future versions of Capistrano will not load the Git SCM
plugin by default. To silence this deprecation warning, add the following to
your Capfile after `require "capistrano/deploy"`:

    require "capistrano/scm/git"
    install_plugin Capistrano::SCM::Git

原因

対応

WARN メッセージにある通り、 Capfile に追記した

+ require "capistrano/scm/git"
+ install_plugin Capistrano::SCM::Git

未解決

WARN メッセージ

/root/repo/vendor/bundle/ruby/2.6.0/gems/activesupport-4.2.11.1/lib/active_support/core_ext/object/duplicable.rb:111: warning: BigDecimal.new is deprecated; use BigDecimal() method instead.

最後に

ruby 2.2.3 から 2.6.2 とマイナーバージョンが4つ上がっただけの様に感じましたが、2.2.3 (2015年8月18日) から 2.6.2 (2019年3月13日リリース) の間に実に3年7ヶ月の時間があり、様々なアップデートが行われていたことがわかりました。

Rails の脆弱性対応も気になっていたので、4.2 系の最新版である 4.2.11.1 にアップデートできたのは安心感があります。

Ruby や Rails を使うメリットの一つに、活発なコミュニティと成熟したエコシステムがあると思います。今後も進化し続けるこの言語/フレームワークを使い続けられる様、しっかりとアップデートに追従していきながら、残念ながら今回はバージョンアップを見送ってしまった gem 達も、アップデートしていきたいと思います。

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3