Ruby on Rails5.0へ移行
こんにちは。開発ユニットbcの堀口です。
URIHO開発を担当しています。
今回は弊社のグループ会社である株式会社トラスト&グロースのサービス「URIHO」で使用しているRuby on Railsについてです。
2017年4月27日にRuby on Rails 5.1が正式リリースされましたね。(Rails 5.1のリリースノートはこちら)
「URIHO」ではRails4.2系を使っていますが、このリリースを機にRails5.1に移行しよう!ということになりました。
それでは、さっそくRails5.1に移行するぞ!...といきたいところですが、まずはリリースノートを見てましょう。
既存のアプリケーションをアップグレードするのであれば、その前に質のよいテストカバレッジを用意するのはよい考えです。アプリケーションがRails 5.0までアップグレードされていない場合は先にそれを完了し、アプリケーションが正常に動作することを十分確認してからRails 5.0にアップデートしてください。アップグレードの注意点などについてはRuby on Railsアップグレードガイド を参照してください。
「Ruby on Rails 5.1リリースノート」 https://railsguides.jp/5_1_release_notes.html
どうやらRails5.1にアップデートする前にRails5.0へアップデートしておく必要があるようです。
というわけで本記事ではRails4.2系からRails5.0へのアップデート手順について紹介します!
アップデートの流れ
Rails5.0アップデートまでの大まかな流れです。
- Rails5.0へのアップデート
- テストを実行
- 警告を表示されないようにする
Rails5.0にアップデート
さっそくRails 5.0にアップデートしていきましょう!
Gemfileの gem 'rails'を以下のようにしました。
gem 'rails', '5.0.0'
これでbundle updateを実行するとRails5.0にアップデートされます。
それではbundle update!
$ bundle update
Bundler could not find compatible versions for gem "activesupport":
In Gemfile:
activesupport (= 4.x.x.x)
rails (= 5.0) was resolved to 5.0.0, which depends on
activesupport (= 5.0.0)
rails (= 5.0) was resolved to 5.0.0, which depends on
activesupport (= 5.0.0)
rails (= 5.0) was resolved to 5.0.0, which depends on
activesupport (= 5.0.0)
....おや?実行してみると何やらエラーメッセージが出てきました。
エラーメッセージを読んでみましょう。
In Gemfile:
activesupport (= 4.x.x.x)
Gemfileではactivesupport の4.x.x.xを要求しています。
rails (= 5.0) was resolved to 5.0.0, which depends on
activesupport (= 5.0.0)
しかし、Rails5.0ではactivesupportの5.0.0に依存しているようです。そのためactivesupportのバージョンでGemfileとRails5.0がコンフリクトしてエラーになっていました。
というわけでactivesupportを5.0.0要求するようにしましょう。
Gemfileを以下のようにしてもう一度bundle updateします。
gem 'activesupport', '5.0.0'
$ bundle update
Bundler could not find compatible versions for gem "railties":
In Gemfile:
devise (= 3.5.6) was resolved to 3.5.6, which depends on
railties (< 5, >= 3.2.6)
rails (= 5.0) was resolved to 5.0.0, which depends on
railties (= 5.0.0)
またエラーメッセージが出てきました。
rails (= 5.0) was resolved to 5.0.0, which depends on
railties (= 5.0.0)
railtiesのバージョンが5.0.0が必要なようですが、Gemfile上にはrailtiesとは書いてありません。
それならばコンフリクトしないはずですが....もう一度メッセージをよく読んでみましょう。
devise (= 3.5.x) was resolved to 3.5.x, which depends on
railties (< 5, >= 3.2.x)
この部分を読んでみるとdevise3.5.xが5.0.0未満のrailtiesを要求していることがわかります。どうやらdeviseの要求しているrailtiesのバージョンでコンフリクトしていたようです。これを解消するにはdeviseをアップデートして対応されていることを祈るしかないです。
RubyのgemはRubyGems.org に公開されており、gemの最新の状態がわかります。さらに詳細を知りたい場合はgithubにアクセスして確認しましょう。それではさっそくdeviseの最新を確認してみます。
おぉ、どうやらrailties5.1.0が入っているようですね。解消していると思われるので、最新のdeviseにアップデートしましょう。
Gemfileを以下のようにしてもう一度bundle updateします。
gem 'devise', '4.3.0'
これで無事Rails5.0アップデート完了です!
となるはずもなく、この後も何度も何度も同じようなエラーメッセージが出ます....
めげずに頑張ってgemをアップデートしていきましょう。幸い、全てgemをアップデートすることで解消しました。
最終的に以下のgemをアップデートしました。
gem | バージョン |
---|---|
activesupport | 5.0.0 |
devise | 4.3.0 |
rspec-rails | 3.7.1 |
rails_admin | 1.2.0 |
seed-fu | 2.3.6 |
jquery-validation-rails | 1.16.0 |
jquery-rails | 4.3.1 |
さあ、これでRails5.0とコンフリクトしていたgemをアップデートしたので、bundle updateを実行します!
$ bundle update
~
Installing jquery-validation-rails 1.16.0
~
Installing activesupport 5.0.0
~
Installing seed-fu 2.3.6
~
Installing jquery-rails 4.3.1
~
Installing rspec-rails 3.7.1
~
Installing devise 4.3.0
Installing rails_admin 1.2.0
~
Bundle updated!
無事にRails5.0へのアップデートが終わりました!これにて本記事は終わり、ありがとうございました!
...とはまだなりません。
Rails5.0にアップデートしたので、Railsの設定ファイルもアップデートする必要あります。Rails4ではrails:updateというコマンドで設定ファイルの新規作成、アップデートを行ってくれていましたが、Rails5.0からはrails app:updateというコマンドに変わりました。
さっそくbundle exec rails app:updateを実行します。
$ bundle exec rails app:update
rails aborted!
LoadError: cannot load such file -- active_model/serializers/xml
またまたエラーメッセージが出ました。今回はgemのバージョンでコンフリクトしているとかではなく、active_model/serializers/xmlがロードできないとのことです。active_model/serializersとはXMLとRubyオブジェクトを相互変換する機能をもつgemです。Rails4.2の時はデフォルトでインストールされていたんですが...
Rails5.0からactive_model/serializers/xmlがどうなったのか調べてみると以下の記述がリリースノートで見つかりました。
3.7 XML シリアライズ
RailsのActiveModel::Serializers::Xmlはactivemodel-serializers-xml gemに移転しました。アプリケーションで今後もXMLシリアライズを使うには、Gemfileに「gem 'activemodel-serializers-xml'」を追加してください。
「Rails アップグレードガイド」 https://railsguides.jp/upgrading_ruby_on_rails.html
というわけでどうやらgem化されて、デフォルトではインストールされなくなったようですね。
Gemfileにactive_model/serializers/xmlのgemを書いてbundle installしましょう。
gem 'activemodel-serializers-xml', '1.0.2'
正常にインストールができたら、もう一度app:updateを実行します。
$ bundle exec rails app:update
rails aborted!
LoadError: cannot load such file -- rails/test_unit/sub_test_task
同じようにrails/test_unit/sub_test_taskが読み込めないとエラーメッセージが出ました。rails/test_unit/sub_test_taskがどういうものかわからないので「rails/test_unit/sub_test_task」で調べてみましょう。
すると以下のようなサイトが見つかりました。
rake commands fail if using rails 5
ここのコメントを読み進めていくとDraperがrails/test_unit/sub_test_taskを使っているようです。
さらに読み進めていくとDraper3.0.0.pre1で対応されていることがわかりました。
さて、原因がわかったのでDraperのバージョンを上げましょう。上げる前に現在の最新バージョンを確認してみるとDraper3.0.1がリリースされているようです。
Gemfileを以下のようにして、bundle updateを実行します。
gem 'draper', '3.0.1'
アップデートが完了したらもう一度、app:updateを実行すると、エラーが解消されて正常に実行されます。
実行されると対話式で設定ファイルの新規作成、アップデートが始まります。
設定ファイルの更新内容と既存内容がコンフリクトすると、どうするのか聞いてきます。ここの対応は各々で違うと思うので一概には言えませんので自分で判断しましょう。
ですが、少なくともroutes.rbはアップデートしなくて良いです。initializersにあるファイルもアップデートしなくても良いファイルがある場合があるので差分をきちんと確認しましょう。
routes.rbはファイルの内容が以下のコメントに上書きされて、今まで設定した内容が全て消えるので、アップデートしても良いことは何もありません。
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
テストの実行
無事Rails5.0にアップデートが完了したので、次はテストを実行していきます。リリースノートによると『質のよいテストカバレッジを用意するのはよい考え』とのことです。さて、「URIHO」のカバレッジはどれほどのものかというと...約84%!そこそこ良いカバレッジだと思うので、テストを実行していきます。
まずはテスト用のDBを用意するためにbundle exec rake db:migrate:reset RAILS_ENV=testを実行します。
さくっと用意してテストを実行していきましょう。
mysql2 0.4.3 is not supported. Please upgrade to 0.4.4+
...残念ながらエラーメッセージが表示されてしまいました。そうあっさりとはいきませんねぇ。気を取り直してエラーメッセージを読んでいきましょう。内容はmysql2 0.4.3がサポートされていないので0.4.4以上に上げてくださいとのことなので、mysql2の最新を確認してそのバージョンにアップデートします。
それではもう一度bundle exec rake db:migrate:reset RAILS_ENV=testを実行します。
$ bundle exec rake db:migrate:reset RAILS_ENV=test
rake aborted!
ActiveRecord::NoEnvironmentInSchemaError:
Environment data not found in the schema. To resolve this issue, run:
bin/rails db:environment:set RAILS_ENV=test
マイグレーションを実行するとこのようなエラーが出る場合があります。Rails5.0からproduction環境へのDBの破壊系タスクの実行を保護する機能が導入されました。ar_internal_metadataテーブルに該当DBがどの環境に紐付くか保存しておく仕組みで、Rails4系から移行の初回実行ではar_internal_metadataが存在しなくエラーになります。その場合はエラーメッセージの指示に従ってbin/rails db:environment:set RAILS_ENV=testを実行しましょう。
bin/rails db:environment:set RAILS_ENV=testを実行後、もう一度bundle exec rake db:migrate:reset RAILS_ENV=testしましょう(そういえば、Rails5.0 からはbundle exec rakeコマンドはrailsコマンドに置き換えることができます。詳しくはリリースノートをご覧ください)。
~
DEPRECATION
WARNING: Directly inheriting from ActiveRecord::Migration is
deprecated. Please specify the Rails release the migration was written
for:
class Classname < ActiveRecord::Migration[4.2]
== 20xxxxxxxxxxxx CreatexxxxxxFiles: migrated (0.xxxx s) =====
~
今度はマイグレーションが実行できましたね。ですが警告が出ています。
警告もきちんと解決していきましょう。まず警告メッセージを読んでみます。
Directly inheriting from ActiveRecord::Migration is deprecated.
どうやらRails5.0からはActiveRecord::Migrationを継承するのは非推奨なようです。さてどうやって解消すればいいのやら...残りのメッセージも読んでいきましょう。
Please specify the Rails release the migration was written
for:
class Classname < ActiveRecord::Migration[4.2]
解消方法が書いてありますね。ActiveRecord::MigrationをActiveRecord::Migration[4.2]に変更してマイグレーションファイル作成時のRailsのバージョンを明示する必要があるようです。
解消方法もわかったので、さっそくマイグレーションファイルを修正していきたいところですが...その修正すべきマイグレーションファイルはなんと約200ファイルほどありました。
ファイルを一つずつ修正するのはかなりの手間なのでできれば避けたいところです...全てのマイグレーションファイルのActiveRecord::MigrationをActiveRecord::Migration[4.2]に置換できたら楽なんだけどなぁ
...ということで、そんな時はエディタの機能をフル活用します!「URIHO」の開発にはAtomというエディタを使っています(Atomについてはこちら)。Atomには指定したディレクト内にあるファイルの中で単語を検索して、別の単語に置換する機能があります。検索する単語にActiveRecord::Migrationを入力、置換する単語にActiveRecord::Migration[4.2]を入力することで、約200ファイルのマイグレーションファイルの変更ができました。
ちなみにですが、シェルで以下のコマンドを実行しても同じことができます。エディタでやるかシェルでやるかはお好みでどうぞ!
grep -l 'ActiveRecord::Migration$' ./db/migrate/* | xargs sed -i 's/ActiveRecord::Migration/ActiveRecord::Migration[4.2]/g'
もう一度マイグレーションファイルを実行して警告が消えていることを確認しましょう。
それではテスト用DBのマイグレーションも終わったのでさっそくテストを実行していきます。
bundle exec rake spec!
$ bundle exec rake spec
DEPRECATION WARNING: The factory_girl gem is deprecated. Please upgrade to factory_bot. See https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md for further instructions.
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 in <class:Railtie> at /usr/local/ruby-2.3.0/lib/ruby/gems/2.3.0/gems/less-rails-2.7.1/lib/less/rails/railtie.rb:15)
DEPRECATION WARNING: ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement.
DEPRECATION WARNING: You are using the a deprecated processor interface Less::Rails::ImportProcessor.
Please update your processor interface:
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super.
DEPRECATION WARNING: [Devise] including `Devise::TestHelpers` is deprecated and will be removed from Devise.
For controller tests, please include `Devise::Test::ControllerHelpers` instead.
~
DEPRECATION WARNING: Passing an argument to force an association to reload is now deprecated and will be removed in Rails 5.1. Please call `reload` on the parent object instead.
~
DEPRECATION WARNING: env is deprecated and will be removed from Rails 5.1 (called from block (3 levels) in <top (required)> at /vagrant/uriho/spec/controllers/bo/assurance_decision_requests_controller_spec.rb:19)
~
DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only
keyword arguments in future Rails versions.
Examples:
get :show, params: { id: 1 }, session: { user_id: 1 }
process :update, method: :post, params: { id: 1 }
(called from block (4 levels) in <top (required)> at /vagrant/uriho/spec/controllers/bo/assurance_decision_requests_controller_spec.rb:51)
~
...FFF..........FFF..
~
xxxx examples, 0 failures
~
NoMethodError:
assert_template has been extracted to a gem. To continue using it,
add `gem 'rails-controller-testing'` to your Gemfile.
~
Failure/Error: scope :scope名, -> { where(ActiveHash名: ActiveHash::Filed名) }
NoMethodError:
undefined method `arel_table' for ActiveHash名:Class
~
警告が出ていますが、テストの実行ができました。
いくつかのテストが失敗しているので、まずはその対応をしていきます。
NoMethodError:
assert_template has been extracted to a gem. To continue using it,
add `gem 'rails-controller-testing'` to your Gemfile.
エラーメッセージを読んでみるとassert_templateはgem化されたとのことです。Gemfileにgem 'rails-controller-testing'と追加することで解消するようです。他にもrails-controller-testingに移行されたメソッドがないか調べてみるとリリースノートに以下の記述が載っていました。
assigns
メソッドとassert_templateメソッドはrails-controller-testing
gemに移転しました。これらのメソッドを引き続きコントローラのテストで使いたい場合は、Gemfileにgem 'rails-controller-testing'
を追加してください。「Rails アップグレードガイド」 https://railsguides.jp/upgrading_ruby_on_rails.html
というわけでRails5.0からはassignsメソッドとassert_template
メソッドがrails-controller-testingに移行されたようです。これらのメソッドを使用している場合はrails-controller-testingをインストールしておきましょう。rails-controller-testingはテストのみで使用するので、Gemfileにはgroup :test doに追加します。
Failure/Error: scope :scope名, -> { where(ActiveHash名: ActiveHash値) }
NoMethodError:
undefined method `arel_table' for ActiveHash名:Class
次のエラーメッセージを読んでみるとarel_tableがActiveHashのクラスに定義されていないということです。しかし、ここではwhereメソッドしか使っていないので問題ないように見えます。Rails5のwhereやArel、ActiveHashで検索してみました。するとこのようなissuesが見つかりました。内容を確認してみましょう。
Error of "undefined method `arel_table'" has raised when I did following test.
# spec/associations/active_record_extensions_spec.rb
describe "#belongs_to_active_hash" do
context "setting by id" do
it "finds the correct records" do
School.belongs_to_active_hash :city
city = City.create
school = School.create :city_id => city.id
School.find_by(city: city).should == city
end
end
end
[] % bundle exec rspec spec/associations/active_record_extensions_spec.rb:207
Run options: include {:locations=>{"./spec/associations/active_record_extensions_spec.rb"=>[207]}}
F
Failures:
1) ActiveHash::Base active record extensions ActiveHash::Associations::ActiveRecordExtensions #belongs_to_active_hash setting by id
Failure/Error: School.find_by(city: city)
NoMethodError:
undefined method `arel_table' for City:Class
# ./lib/active_hash/base.rb:274:in `method_missing'
# ./spec/associations/active_record_extensions_spec.rb:207:in `block (5 levels) in <top (required)>'
「raise error "undefined method `arel_table'" in rails 5 #151」 https://github.com/zilkey/active_hash/issues/151
どうやら同じ問題が起きて困っている方がいたようです。無事にこの問題は解決しているのでしょうか。読み進めていきましょう。
ActiveHash does not support arel behaviour. so you should do like this
School.find_by(city_id: city.id).should be school
If you want to write like your sample, pull request is welcome ?
Thanks.
「raise error "undefined method `arel_table'" in rails 5 #151」 https://github.com/zilkey/active_hash/issues/151
この方によるとActiveHashはarelをサポートしていないので、idまで指定する必要があり、この問題の対応のプルリクエストを待ってるよとのことです。こちらとしてはActiveHashを使用している箇所はかなりあるのでこのままでいきたいのですが....
その後も色々調べてみましたが、whereメソッド、find_byメソッドでのみ起こるようです。対応としてはidまで指定する以外どうしようもないことがわかりました。
というわけで一つずつファイルを修正していきます。先ほどと同じようにAtomで置換できればいいのですが、他にもcreateやupdateでActiveHashを使っているので、残念ながら置換はできません...というわけで約120ファイルの修正を行っていきます。修正後はもう一度テストを実行しましょう。テスト実行後も同じエラーが出た場合は、修正漏れがありますので、根気強く直していきましょう...
$ bundle exec rake spec
~
.....................
~
xxxx examples, 0 failures
...ついにエラー0で実行できました。無事にテストの実行が完了しました!
警告への対応
さて、無事にテストの実行ができたので、今度こそ終わりにしたいところですが...
警告もきちんと対応していきましょう。警告をよく読んでみるとRails5.1から廃止予定という内容のものもあります。
DEPRECATION WARNING: The factory_girl gem is deprecated. Please upgrade
to factory_bot. See
https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md
for further instructions.
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
DEPRECATION
WARNING: ActiveRecord::Base.raise_in_transactional_callbacks= is
deprecated, has no effect and will be removed without replacement.
DEPRECATION WARNING: You are using the a deprecated processor interface Less::Rails::ImportProcessor.
Please update your processor interface:
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
DEPRECATION
WARNING: alias_method_chain is deprecated. Please, use Module#prepend
instead. From module, you can access the original method using super.
DEPRECATION WARNING: [Devise] including `Devise::TestHelpers` is deprecated and will be removed from Devise.
For controller tests, please include `Devise::Test::ControllerHelpers` instead.
DEPRECATION
WARNING: env is deprecated and will be removed from Rails 5.1
DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only
keyword arguments in future Rails versions.
Examples:
get :show, params: { id: 1 }, session: { user_id: 1 }
process :update, method: :post, params: { id: 1 }
上から順々に対応していきましょう。
DEPRECATION WARNING: The factory_girl gem is deprecated. Please upgrade
to factory_bot. See
https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md
for further instructions.
どうやらfactory_girlがfactory_botに名称が変わるようです(詳細はこの辺りを見てもらえると)。まさかブログ執筆中に変わることになるとは...運が良いのやら悪いのやら。それに伴ってインストールするgemもgem "factory_girl_rails"からgem "factory_bot"に変更しなければなりません。さっそくインストールしてみましょう。
factory_botに変わったことで今までfactory_girlを使っていた箇所をfactory_botに変更する必要があります。FactoryGirlをFactoryBotに置換していきましょう。ここでもActiveRecord::Migration[4.2]と同じように全て置換してしまって問題ありません。置換が完了後、テストを実行してfactory_girlの警告が消えていることを確認しましょう。
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
DEPRECATION WARNING: You are using the a deprecated processor interface Less::Rails::ImportProcessor.
Please update your processor interface:
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
次はこの警告を対応していきましょう。内容はsprocketsがregister_engineという廃止予定のもので実装しているようです。しかし、Gemfileにはsprocketsと書いていないので、他のgemが依存していると思われます。残りのメッセージも確認してみましょう。
DEPRECATION WARNING: You are using the a deprecated processor interface Less::Rails::ImportProcessor.
Please update your processor interface:
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
この部分を読んでみるとどうやらless-railsが原因のようですね。
対応されているか最新を確認してみましょう。
見たところsprocketsのバージョンが2以上4未満となっているので対応されていそうな雰囲気です。とりあえず、対応されていることを祈ってless-railsをアップデートしてテストを実行しましょうか。
$ bundle exec rake spec
DEPRECATION
WARNING: ActiveRecord::Base.raise_in_transactional_callbacks= is
deprecated, has no effect and will be removed without replacement.
DEPRECATION
WARNING: alias_method_chain is deprecated. Please, use Module#prepend
instead. From module, you can access the original method using super.
DEPRECATION WARNING: [Devise] including `Devise::TestHelpers` is deprecated and will be removed from Devise.
For controller tests, please include `Devise::Test::ControllerHelpers` instead.
~
DEPRECATION
WARNING: env is deprecated and will be removed from Rails 5.1
~
DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only
keyword arguments in future Rails versions.
Examples:
get :show, params: { id: 1 }, session: { user_id: 1 }
process :update, method: :post, params: { id: 1 }
~
...どうやら祈りが通じたようですね。警告が消えていますので対応されていたようです。
この調子で次の警告も解消していきましょう!
DEPRECATION WARNING:
ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has
no effect and will be removed without replacement.
raise_in_transactional_callbacksが廃止予定のようです。after_rollback
コールバックやafter_commit
コールバックを定義すると、警告が表示されるようになっていましたがraise_in_transactional_callbacksを設定することで警告が出なくなっていました。ですが、Rails5.0からこの設定をしなくてももう警告が出なくなったようなので、この設定を削除してしまいます。
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use
Module#prepend instead. From module, you can access the original method
using super.
alias_method_chain が廃止予定とのことですが、「URIHO」ではlogger.rbとar_innodb_row_format.rb、独自実装したファイルで使用しています。
一つずつalias_method_chainの対応の仕方が違うのでそれぞれ説明していきます。
まずlogger.rbですが、実装していた処理とdevelopment.rbのconfig.assets.quiet = trueが同じ動作をしてくれていました。実装していた処理を削除して、development.rbにconfig.assets.quiet = trueを追加して対応できました。
次にar_innodb_row_format.rbですが、こちらはすでに以下のように修正している方がいらっしゃったのでそちらを利用しました。
ActiveSupport.on_load :active_record do
module ActiveRecord::ConnectionAdapters
module CreateTableWithInnodbRowFormat
def create_table(table_name, options = {})
table_options = options.merge(options: 'ENGINE=InnoDB ROW_FORMAT=DYNAMIC')
super(table_name, table_options) do |td|
yield td if block_given?
end
end
end
class AbstractMysqlAdapter
prepend CreateTableWithInnodbRowFormat
end
end
end
「Rails(ActiveRecord)とMySQLでutf8mb4を扱う設定」https://qiita.com/xend/items/4d5c3333cbae53888f37
さて、問題は独自実装しているファイルです。こちらはある処理をするモジュールを作成していましたが、動的にalias_method_chainを使っています。
module モジュール名
def メソッド名(names)
begin
names.each do |name|
self.new.send("#{name}=", nil)
define_method("#{name}_with_number=") do |value|
#処理
send("#{name}_without_number=", value)
end
#alias_method_chainを設定
alias_method_chain "#{name}=", :number
end
end
rescue ActiveRecord::StatementInvalid => e
end
end
動的にalias_method_chainを使用していたので、alias_method_chainを使わないように改修することになりました。良い方法がないかと色々調べてみましたが動的にalias_method_chainを使っていて、それの改修方法を載せている方もおらず、このモジュールを実装し直すことになりました。しかし、どう直したものかと悩んでいるとユニットメンバーの先輩が以下のように改修してくれました。
module モジュール名
class_methods do
def メソッド名(*names)
names.each do |name|
define_method("#{name}=") do |value|
#処理
write_attribute("#{name}".to_sym, value)
end
end
end
end
end
実装していたメソッドをクラスメソッドとして定義し、引数に与えられたnameメソッドをdefine_method("#{name}=") で上書きすることで以前実装していた内容と同じ処理を行うことができました。これによりalias_method_chainの警告は全て解消されました。先輩に感謝です。
DEPRECATION WARNING: [Devise] including `Devise::TestHelpers` is deprecated and will be removed from Devise.
For controller tests, please include `Devise::Test::ControllerHelpers` instead.
DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only
keyword arguments in future Rails versions.
Examples:
get :show, params: { id: 1 }, session: { user_id: 1 }
process :update, method: :post, params: { id: 1 }
こちらの2つの警告は内容通り、Devise::TestHelpersをDevise::Test::ControllerHelpersに、テスト時のリクエストにパラメータを渡す時はparamsのhashの形に変更しましょう。<br/>
reload
<pre><code>DEPRECATION WARNING: env is deprecated and will be removed from Rails 5.1 </code></pre>envが廃止予定でRails5.1から削除されているとのことです。この問題はenvと書いてある箇所を@request.envにすることで解消します。ですが、URIHO上のソースでは@request.envしか使っておらずenvを使っている箇所はありませんでした。何が原因だー!と調べているとまたも先輩が助けてくれました。原因はgonというgemでした。このgemがenvを使っているようです。gonの<a href="https://rubygems.org/gems/gon/" target="_blank">最新</a>を調べてアップデートしましょう。<br/>
<pre><code>DEPRECATION
WARNING: Passing an argument to force an association to reload is now
deprecated and will be removed in Rails 5.1. Please callon the parent object instead</code></pre>こちらの警告はテストデータであるFactoryBotのファクトリーを定義するときに<br/>
:nothing
<pre><code>factory ファクトリー名, class: クラス名 do
~
association クラス名, factory: ファクトリー名
~
end
</code></pre>このようにアソシエーションしていました。ですが調べてみるとこの箇所でこの警告が発生していました。アソシエーションしているファクトリーが原因かと思っていましたが、アソシエーションしているファクトリーの詳細は以下のようになっています。<br/>
<pre><code>factory ファクトリー名, class: クラス名 do
after(:build) do |element|
element.object create ~
end
end
</code></pre>特別変わった実装はしておらず、afterメソッドを使っているだけです。ですが、調べてみるとなんと原因はafterメソッドでした。とは言ってもこのファクトリー自体は問題ありません。では、何が問題かというとafterメソッドを使用しているファクトリーをアソシエーションしていたことです。<br/>
対応としては該当箇所のアソシエーションをやめ、アソシエーションしていたファクトリーの内容をcretateメソッドで処理するようにして解消しました。<br/>
<pre><code>DEPRECATION WARNING:option is deprecated and will be removed in Rails 5.1. Use
head` method to respond with empty response bodyrender :nothingはRails5.1で廃止予定とのことなので、警告の内容通りにrenderをheadに変更します。headは応答ステータスとヘッダ情報のみを表示するメソッドで、引数にHTTPステータスを渡すことで、引数のHTTPステータスを表示します。RailsのHTTPステータスのシンボルはRails コンソールなどでRack::Utils::SYMBOL_TO_STATUS_CODEで確認できます。
irb(main):001:0> Rack::Utils::SYMBOL_TO_STATUS_CODE
=>
{:continue=>100, :switching_protocols=>101, :processing=>102,
:ok=>200, :created=>201, :accepted=>202,
:non_authoritative_information=>203, :no_content=>204,
:reset_content=>205, :partial_content=>206, :multi_status=>207,
:already_reported=>208, :im_used=>226, :multiple_choices=>300,
:moved_permanently=>301, :found=>302, :see_other=>303,
:not_modified=>304, :use_proxy=>305, :temporary_redirect=>307,
:permanent_redirect=>308, :bad_request=>400,
:unauthorized=>401, :payment_required=>402, :forbidden=>403,
:not_found=>404, :method_not_allowed=>405,
:not_acceptable=>406, :proxy_authentication_required=>407,
:request_timeout=>408, :conflict=>409, :gone=>410,
:length_required=>411, :precondition_failed=>412,
:payload_too_large=>413, :uri_too_long=>414,
:unsupported_media_type=>415, :range_not_satisfiable=>416,
:expectation_failed=>417, :misdirected_request=>421,
:unprocessable_entity=>422, :locked=>423,
:failed_dependency=>424, :upgrade_required=>426,
:precondition_required=>428, :too_many_requests=>429,
:request_header_fields_too_large=>431,
:unavailable_for_legal_reasons=>451, :internal_server_error=>500,
:not_implemented=>501, :bad_gateway=>502,
:service_unavailable=>503, :gateway_timeout=>504,
:http_version_not_supported=>505, :variant_also_negotiates=>506,
:insufficient_storage=>507, :loop_detected=>508,
:not_extended=>510, :network_authentication_required=>511}
render :nothingでは404を返す箇所があったのでheadに:not_foundを渡すことで対応しました。
これで無事全ての警告が解消し、すっきりした状態でテストが実行されます。
さて、これでRails5.0への移行は完了です。いかがでしたでしょうか?お役に立てれば幸いです。
いやーRails5.0への移行は想像以上に険しい道のりでした。ユニット内で週に1回集まって進めていたので半年近くかかりました。今後、Rails5.1にアップデートもする予定ですが、Rails5.0への移行より苦戦しないことを祈るばかりです...
以上、Rails5.0への移行でした!