初めまして、心は永遠に新卒のエンジニア、undoです。 9月末、TMIXがrails5化(5.0系列最新の5.0.5化)されました。 そのときやったことやハマったことなどの覚え書きをしていこうと思います。
Rails5
歴史的経緯により、TMIXは複数のRailsアプリケーションが共通のRDBを参照しに行く構成になっています。 今回自分が行ったのは、そのうちtmix-webと呼ばれるアプリケーションで、ざっくりいえばお客様に直線触れていただくところがメインになります。 これ以外のTMIXに関連するアプリケーションは既にRails5へのアップデートが完了していましたが、一番大きなアプリケーションであり、複雑な箇所や他に依存している箇所が多いことで、Rails5化するまでに時間が掛かりました。
作業を始めたのは2017年8月某日、当時5.0系列で最新だった5.0.5にアップグレードする形にしました。
アップグレード手順
Rails4→Rails5ということで、仕様の変更など手間取るところが幾つかありました。 以下参考までに行った作業など。
RailsのGem update
- Gemfileのバージョンを5.0.5に書き換えます。
-gem 'rails', '4.2.9' +gem 'rails', '5.0.5'
- bundle updateコマンドを実行します。
$ bundle update rails
関連Gemのupdate
$ bundle update
rails5の設定に対応
$ rails app:update
ApplicationRecordをActiveRecordのモデルのベースクラスにする
Rails5 からは各 model は ActiveRecord::Base ではなく ApplicationRecord を継承するようになりました。それに合わせて修正していきます。
//app/models/application_record.rb class ApplicationRecord < ActiveRecord::Base self.abstract_class = true end
次に、各モデルクラスの継承関係を変更します。例えば
- class Hoge < ActiveRecord::Base + class Hoge < ApplicationRecord
この後は、落ちているテストを見ながら、Rails5化による仕様の変更などに対応していきます。以下覚え書きです。
skip_before_actionにraise: falseを追加
同一ファイル内にcallback関数がない場合、raiseオプションにfalseを設定しない場合、ArgumentErrorが出るように変更されました。
テスト用のgem rails-controller-testingを追加
controllerのテストで assigns などを使う場合は rails-controller-testing の gem が必要になりました。
./config/application.rb にAutoloadの許可を追加
Rails5からproduction環境でのみAutoloadが廃止になりました。 lib以下に定義している場合など、許可をしたい場合は以下の記述が必要になります。
config.enable_dependency_loading = true
Rails5で非推奨になったメソッドの変更
before_filter
をbefore_action
に変更uniq
をdistinct
に変更render :text
をrender :plain
に変更render nothing: true
をhead :no_content
に変更 このへんはそのまま置き換えていけば大丈夫そうです。redirect_to: back
をredirect_back
に変更
redirect_to :back, notice: '入力されていない項目があります'
redirect_to を利用する場合は上記のようにオプションでメッセージを記述できましたが、redirect_backはどうやらできないようです。
redirect_back(fallback_location: root_path) flash[:notice] = '入力されていない項目があります'
諦めて別々に書きます。
Arelを使っているところの修正
軽く説明。ArelはActive Recordの内部で使用されるSQL生成ライブラリです。 Arelを使うと文字列でSQLを書くことなく、Rubyのコードとしてクエリを書くことが出来るという便利なものですが、ArelはRailsのプライベートAPIであるため、完全にサポートされていません。アップグレード時の保証がありません。
今回Rails5にアップグレードしたことで、そのArelを使っていたところが盛大に壊れてしまいました。 幸い、壊れた箇所はArelでなくとも問題ない箇所だったため、先輩がArelを使わない記述にリファクタリングしてくれました :smile:
RSpecの警告・仕様変更
上述した対処で動作はするようになりましたが、RSpecの仕様変更などによってテストが落ちている点がいくらかありました。
paramsがnilを受け取らなくなった
params: nil
のように定義するとparams: ""
として受け取るようです。
そのため
before { params.merge!(hoge: nil) }
のように記述していたところを
before { params.delete(:hoge) }
に書き換えました。またそれに合わせて該当Controllerの処理も書き換えました(nil?ではなくてpresent?に)
get、postなどで渡すパラメータの仕様変更
Rails5 からActionController::TestCase
が非推奨になったので、それに合わせて記述を変更します。
- get :callback, hoge: "fuga" + get :callback, params: { hoge: "fuga" }
だいたいこのへんでテストOKになりました。 他にもwarningを可能な限り潰していきました。
アップグレードを終えて
Rails 5 にすることで、様々な新機能が使用できるようになります。 お客様には直接関わりのないところですが、より開発しやすく、バグや脆弱性の少ない新しいバージョンにすることで、エンジニアとしてより良いサービスを作り続けられることに繋がると思います。 次は5.1系列へのアップグレードですね!