見出し画像

Rails 5.1.6 to 5.2.4.4, Ruby 2.5.1 to 2.6.6

こんにちは、taskeyの田代です。

弊社サービス

皆さん、ライブラリのUpgradeしてますか?

セキュリティのメンテナンスや、言語の新機能への追従、そのライブラリ自身の拡張を享受する為に、定期的なUpgradeはとても大切です。
さらに、最新への追従というのはOSSコントリビュートチャンスだったりもします。楽しく愉快な巨人の肩ライフには必須ですね。

RailsやらのUpgradeの知見は巷に溢れていますが、細かいライブラリのUpgrade時の注意点をVersionが細かく記載してある記事はどれだけあっても無駄にはならないと思うで、こちらで残しておきます。

今回はRails: 5.1.6 to 5.2.4.4、Ruby 2.5.1 to 2.6.6、その他のgemでのupgradeが対象です。
※ 注意点があったライブラリのみ記載

ちなみに

RailsのUpgrade手順に関しては伊藤さんの記事を参考にさせて頂いております。
思えばエンジニアになりたての時、Rspecを覚えられたのも伊藤さんの記事です。(元バンドマンと聞いたことが有りますし、いつかお礼も兼ねてお話してみたいなぁ)

factory_bot 4.8.2 to 6.1.0

多分今回のUpgradeでコード書換が一番多く発生した変更でした。
静的に属性を設定する場合、下記コードのようにblockで渡すことが必須となりました。

【Upgrade前】

FactoryBot.define do
 factory :user do
   name '名前' ※ blockで渡さなくてもOK
 end
end

【Upgrade後】

FactoryBot.define do
 factory :quest do
   name { '名前' } ※ block必須
 end
end

こちらは5.0.0での変更です。

ちなみに警告は4.11.1から出ていたようです。
メジャーバージョン2つ飛ばしで結構無茶をしたのですが、Test用ですし、まぁ、良しとしましょう。
※ changelogは読みましょう。

Rubocop 0.51.0 to 1.8.1

Rubocop最高ですよね。入れてよかったgem堂々の1位です。
ある程度育っているプロジェクトに導入するのは本当に大変ですが、その価値はあります。

こちらも思いっきりUpgradeしちゃいました。

 - 0.72でrubocopからRails Copsが外された
 - 計測方法が変わったらしく、ABCsizeやCyclomatic, PerceivedComplexityの計測値が変更される
 - 1.0で新規のルールが一気に開放される

0.72 の段階でRails Copsがrubocop本体から切り離された為、Railsを使っている方は別途rubocop-railsというgemを入れる必要があります。
詳しくはrubocopコミッターのkoicのこちらの記事を見て下さい。

また、1.0での新規ルール追加(NewCop optionで切替可能)の追加と、計測方法の変更により現状のコードではめちゃめちゃ警告が出るようになってしまいます。

ライブラリの追従に重きを置く場合、 bundle exec rubocop --auto-gen-config してtodo.yml を作成して一旦後回しにしましょう。
コツとしてはtodo.yml内のEnabled: falseになっているもののみ出来るだけ解消しておくとメリットの享受が出来ますね。
※ 落ち着いたタイミングでtodo.ymlは片付けていきましょう。

activerecord-import 0.20.2 to 1.0.7

1.0.0リリースのタイミングで、Mysqlにおけるon_duplicate_key_update optionのdefault値が変更されました。

【<= 0.28.2】
User.import users
※ on_duplicate_key_updateのdefault値が設定されていなくても、uniqカラムが重複する場合upgradeとなった

【>= 1.0.0】
User.import users, on_duplicate_key_update: [:id]
※ on_duplicate_key_updateのdefault値が設定されたいない場合エラーが発生するため、明示的に示す必要がある

これは結構大きい変更ですので、気をつけて下さい。
テストケースが十分でない場合、気づけず不具合が発生してしまう可能性もあります。

carrierwave 1.3 to 2.1

ハマりました。
Transactionが終了して保存される前にuploadされるpathが2.0.0で変更されていました。Transaction内で複数レコード更新の際に、参照してしまったりすると、思わぬ挙動を起こします。

【<= v1.3】 ※ 保存後と同じpath
- /uploads/user/5847843528007c73ea5cf3e9a67cebbccec86f42/image-20210121092443.jpg

【>= v2.0】 ※ tmp/ に一時的に保存される。
- /uploads/tmp/1611188862-940951635243840-0001-1147/image-20201211110353.jpg

carrierwaveの現在のmasterブランチでは下位互換に関しての記述があります。が、未リリースなようで、リリースされてからのUpgradeにしようと思っています。

CarrierWave.configure do |config|
 config.fog_credentials = {
   省略
   endpoint:              'https://s3.example.com:8080' # optional, defaults to nil
 }
 config.fog_directory  = 'name_of_bucket'                                      # required
 config.fog_public     = false                                                 # optional, defaults to true
 config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
 # For an application which utilizes multiple servers but does not need caches persisted across requests,
 # uncomment the line :file instead of the default :storage.  Otherwise, it will use AWS as the temp cache store.
 # config.cache_storage = :file ※ この部分 まだ、リリースしていない
end

puma 3.10.0 to 5.1.1

こちらは5.0.0における変更のmdがまとまっています。

各種実験的機能も気になりましたが、そちらの検証はまたの機会に回します。
注意点として、Rails sでの起動アドレスが変更されています。

【Upgrade前】
| [121]Pumastartinginclustermode...
| [121] * Version3.10.0(ruby2.5.1-p57),codename:Russell'sTeapot
| [121] * Minthreads:1,maxthreads:1
| [121] * Environment:development
| [121] * Processworkers:2
| [121] * Phasedrestartavailable
| [121] * Listening on tcp://0.0.0.0:3000
| [121] UseCtrl-Ctostop
| [121] -Worker0(pid:138)booted,phase:0
| [121] -Worker1(pid:148)booted,phase:0

【Upgrade後】
| [318] Puma starting in cluster mode...
| [318] * Puma version: 5.1.1 (ruby 2.5.1-p57) ("At Your Service")
| [318] *  Min threads: 1
| [318] *  Max threads: 1
| [318] *  Environment: development
| [318] *   Master PID: 318
| [318] *      Workers: 2
| [318] *     Restarts: (✔) hot (✔) phased
| [318] * Listening on http://127.0.0.1:3000 ※ アドレスがループバックアドレスに変更されている。
| [318] Use Ctrl-C to stop
| [318] - Worker 0 (PID: 333) booted, phase: 0
| [318] - Worker 1 (PID: 337) booted, phase: 0

ngrokだったり、CMSが切り離されていたりする場合、通信ができない場合がありそうですので、Rails s 時に -b '0.0.0.0' してあげると以前のアドレスと同様で立ち上がります。

ActiveModelSerializers 0.10.6 to 0.10.12

失敗しました!
原因は10.0.7で入ったこちらの変更になります。

collectionのシリアライズ時にから配列の場合エラーが出てしまうというものです。

【<= version 10.0.6::ActiveModelSerializers::SerializableResource.new(
 collections, # [] empty array
 each_serializer: CollectionSerializer,
).serializable_hash
=> { collection_types: nil }

【>= version 10.0.7::ActiveModelSerializers::SerializableResource.new(
 collections, # [] empty array
 each_serializer: CollectionSerializer,
).serializable_hash
=> Raise ArgumentError  "Cannot infer root key from collection type. Please specify the root or each_serializer option, or render a JSON String"

issuesも追加したので手が空いた時にPR出してみます。
さすがにプロダクトコードの変更箇所が増えすぎてしまうのでUpgradeは一旦断念です。

RailsとRubyのupgrade

RailsとRubyに関しては既出だと思うので個人的に嬉しかったことを上げさせていただきます。

【Rails】
 - Responseが何もしていないのに平均20ms下がりました👏
 - メモリ使用率は3%ほどあがったけど最近のインフラはメモリ潤沢だからAll OK👍

【Ruby】
 - rangeの終端省略出来るの嬉しい! ※ rubocopでも見てくれます。
 - Proc#<<< #>>の関数合成かっこいい👏
 - Enumerable#chain便利そう🤔

まとめ

まだ道半ばではありますが、Upgradeの基盤と知見が整ったので、これから最新にも追従していきたいと思います。

Upgradeにより、OSSの足りていない点も見つかります。
最新追従が出来ているということは、コントリビュートチャンスをつかみやすい環境を作れることに繋がると、強く感じました。やっていきですね。

昨今RubyのメジャーUpgradeもありましたし、今年中には最新に追いつこうと思います。巨人の肩乗ってっちゃいます!!!

募集

弊社正直、エンジニアが足りてません!!!

Serverエンジニアに関して、下記現状です!!!
ご興味有る方是非ご連絡くださいー!!!

アピールポイント

・ Spec整備済み
・ OpenAPI 整備済み
・ 機能開発毎にエンジニアで設計や命名を話し合う風習あり
・ データマート(BigQuery)整備済み
・ Deployフロー整備済み
・ 負債に対しての定期的なMTGと、それを解像度高く分解して実行できる環境
・ ECS on Fargate、Aurora Auto Scaling とモダンなインフラを採用
・ データ分析、SRE、フロントエンド(React)、リコメンドエンジン等の幅の広いスキルの拡張が可能


現状の課題

・ 現状がRails5系、Ruby2.6系と、最新のバージョンへの追従が遅れている
=> 直近でVersionUP予定あり
・ APIで返却するJSONが最適化されていない
=> JSON整備予定あり
・ JSONResponse返却のGetRequestに対してのCDN整備が整っていない
=> 長期的観点でCDN導入予定
・施策速度優先とエンジニア不足により技術的負債を解消し切れていない  => DX、開発効率を上げていくためにも必須

この記事が気に入ったらサポートをしてみませんか?