patorashのブログ

方向性はまだない

7年開発しているプロジェクトをRails6にアップグレードした

Railsのアップグレード作業は検証含めて非常に面倒なもので、結構遅れがちなのですが、どこかで気合い入れてやらなければなーと思い、エイヤッとやってやりました。Rails3からやってるプロジェクトなので負債もまだまだ多いですが、とりあえずメジャーバージョンアップさえしておけば、他の技術も徐々に対応できるはず…。今回のアップグレードは5.2系から6.0系へのアップグレードです。

今回のアップグレードでやったこと

トレンドに追従できていないのは全然わかっていますが、頑張って追いかけるためにやれることはやっていきます😀

  • Sprocketsを3から4に変更した
  • sass-railsを6に変更した
  • therubyracerをmini_racerに変更した
  • Rails6をインストールしてbin/rails app:updateで差分を反映した
  • belongs_toにoptional: trueを付けていった
  • app/views/以下にある*.js.coffeeのファイルを*.js.erbに変更してCoffeeScriptからJavaScriptに修正した
  • Rails6からのローダーであるzeitwerkに対応するため、bin/rails zeitwerk:checkを行い、クラス名を修正したり等を行なった
  • ActionDispatch::HostAuthorizationを有効にするためにconfig.hostsに設定を行なった
  • credentials機能をバックポートしていたので、それを削除した

個別に解説するのもあれなので、ざっくりと書いていきます。

Sprocketsを3から4に変更した

まず雑にRails6系にしてbundle update railsをしたら、色々と怒られまして、その中に入っていたと思います。これはSprockets3系に依存していたgemがあったためでした。たしか、css_spritterだったかなと思います。これはIE9が1ファイルに付き4096までしかセレクタ定義を認識できないため、それ以上の定義を使おうと思ったらファイル分割するしかない、というやつですね。

これは昔、私がqiitaに記事を書いてます。

qiita.com

もうIE9のサポートは打ち切ったので、これを削除し、Sprocketsのバージョンを4系にしました。 この辺りでsass-railsを6にするのもなんか時間かかった気がしますが、何が原因だったか忘れました。

therubyracerをmini_racerにした

mini_racerの存在に気づいたのがつい最近というレベルで知らなかったのですが、以下の記事は3年前の記事です。これといってtherubyracerに依存しているようなものはないだろう、と思って変更しました。テストも通っているので大丈夫でしょう。

note.com

belongs_toにoptional: trueを付けていった

これはもう以前のバージョンの時点でやっておくべきだったことですが、放置していたので対応しました。belongs_toをつけると関連先がデフォルトで必須になる件です。config.load_modules 6.0に設定して、頑張って直しました。

views以下のjs.coffeeをjs.erbに修正した

これは、assets以下のほうはjs.coffeeで動くのですが、views以下のほうがjs.coffeeを認識しなくなっていました。Ajaxでアクセスされた際に返すViewが以前は自動的にjs.coffeeになっていたのだけれど、ファイルの存在を認識してくれないからhtml側のViewを返してしまってエラーになっていました。

このままで動く方法を探そうとしたのですが、いまいちわからず…。Railsがcoffeeをサポートしなくなったからなんでしょうか?直し方がわからなかったので、拡張子のjs.coffeeをjs.erbに変換して、ファイルの内容もCoffeeScriptからJavaScriptに直したら、普通にAjaxで認識してくれるようになりました。

Ajaxで返す際のCoffeeScriptでは、大したことをしていなかったのでJSへの修正も簡単、かつファイル数も少なかったため、手動で直して終わり、としました。

zeitwerk対応

bin/rails zeitwerk:checkを行い、クラス名の修正等を行ないました。

zeitwerkはフォルダ構造とファイル名からnamespaceやクラス名を推測してロードを試みるため、多少の修正が必要でしたが、先ほどのコマンドで「こう直してほしい」と言われるので、大したことはありませんでした。一斉置換で対応可能でした。

ActionDispatch::HostAuthorization対応

これは、DNSバインディング攻撃から保護するために追加されたミドルウェアの設定です。

config/application.rbやconfig/environments/production.rbなどで設定しておくと、設定されたドメイン以外でのアクセスを受けたらエラーになってくれます。

いろんなサブドメインで検証することもあるので、config/application.rbで以下のようにしました。(example.comはプロダクトのドメインに置き換えてください) .example.comとすることで、サブドメインワイルドカードにすることができます。

config.hosts.push 'example.com', '.example.com'

設定はこれでいいのですが、インテグレーションテストを実行すると、この設定が仇となってエラーになります。

そこで、config/environments/test.rbの最後で、クリアしておきます。

config.hosts.clear

これで、テストも無事実行されるようになりました。

credentials機能をバックポートしていたので、それを削除した

これは以前に記事にした通り、Rails6系のcredentialsの機能を5.2にバックポートしていたのですが、正式に6系にしたため、不要になりましたので、削除しました。

patorash.hatenablog.com

削除した後に動作検証をして、問題ないことを確認しました。

これからやりたいこと

あくまでも私見ですが…

  • CoffeeScriptをやめる
  • Sprockets4からWebpackerに移行する
  • bootstrap3から4に移行する
  • knockout.jsからstimulusに移行する
  • turbolinksを導入する

周回遅れ感がありますが、保守をしつつ、機能追加をしつつ、アップグレードしていくのは大変なのです😢若者がプロジェクトに入ってくれることになっているのですが、若者に今更CoffeeScriptとかやってもらうのは厳しいと思うので、本格的にアサインする前にこれらの一部でも倒しておきたい所存…。やっていくしかない。