【不定期配信】最新のRuby & Railsへのバージョンアップ時の注意点 (~ 2021-10-14)
Ruby の最新情報は nagachikaさん (@nagachika) / Twitter が ruby trunk changes 、Rails の最新情報は TechRacho|BPS株式会社のRuby on Rails開発情報サイト が 週刊Railsウォッチの記事一覧|TechRacho by BPS株式会社 で公開してくださっています。両記事ともに大変有益な情報です。ありがたいことです。
本記事ではそれらの情報を元に Ruby と Rails を安定して使い続けるために最新の Ruby と Rails に対して行われた変更がバージョンアップするときに問題になるかどうかという観点で情報をまとめています。
Google広告
Ruby
仕様変更の一覧
ruby 3.0
$LOADED_FEATURES
Google広告
ruby trunk
ruby-trunk-changes 2021-10-11 - ruby trunk changes
OK
relineの開発が活発ですね。すごい!
[ruby/ipaddr] Make IPAddr#include? consider range of argument · ruby/ruby@9a321dd
OK
net4 = IPAddr.new("192.168.2.0/16")
みたいにnetmaskを指定できるようになったみたい。
ruby-trunk-changes 2021-10-12 - ruby trunk changes
OK
ruby-trunk-changes 2021-10-13 - ruby trunk changes
[ruby/digest] Bump version to 3.1.0.pre0 · ruby/ruby@e94bcda
[ruby/digest] Bump version to 3.1.0.pre1 · ruby/ruby@ab787c4
[ruby/digest] Bump version to 3.1.0.pre2 · ruby/ruby@01dc55f
OK
digestのバージョンが3.0.1.preから3.1.0.pre2に上がっています。ざっと 修正内容 をみたけど仕様変更はなさそう。JRuby対応とCIに関する修正が主なもの。
ruby-trunk-changes 2021-10-14 - ruby trunk changes
OK
以下のように標準添付ライブラリのバージョンが更新されています。バージョン番号しか変わっていないような気がしますが、変えるとどのような影響があるのでしょうかね。
- zlib: 1.1.0 から 2.1.0
- json: 2.5.1 から 2.6.0
- fcntl: 1.0.0 から 1.0.1
- benchamark: 0.1.1 から 0.2.0
- cgi: 0.2.0 から 0.3.0
- timeout: 0.1.1 から 0.2.0
- yaml: 0.1.1 から 0.2.0
- find: 0.1.0 から 0.1.1
- nkf: 0.1.0 から 0.1.1
- base64:0.1.0 から 0.1.1
追記: @nagachika さんからのコメント。なるほど!
なお標準添付ライブラリのバージョンbumpされてるのは、3.1.0 リリース時に default gems 化されているものは変更点があったらバージョンを上げておかないと、RubyGems で公開されているものと不整合が起きてbundlerでの解決とかsecurity fix時の影響バージョンのアナウンスとかに問題が起きるからかと
— nagachika (@nagachika) October 15, 2021
ruby 3.0
merge revision(s) 89242279e61b023a81c58065c62a82de8829d0b3,529fc204af… · ruby/ruby@fe9d33b
OK
修正前は Marshal.load の proc の戻り値に対して freeze すると例外が挙がっていたが、例外が挙がらないようになり freeze できるようになった。
merge revision(s) 60d0421ca861944459f52292d65dbf0ece26e38a,b6534691a1… · ruby/ruby@2c947e7
【仕様変更】
$LOADED_FEATURES
のエンコーディングをファイルシステムのデフォルトエンコーディングに修正。修正前はエンコーディングが binary になっていたようです。 $LOADED_FEATURES
を使っている箇所は影響がある。
[merge revision(s) abc0304cb28cb9dcc3476993bc487884c139fd11: Backport… · ruby/ruby@cfad058
OK
Regexp#matchの修正。レースコンディションでのbackrefの改善。互換性あり。
ruby 2.7
変更なし。
Rails
仕様変更の一覧
Rails 7.0
- ActiveRecord / ActiveModel
- has_secure_password (ActiveModel::SecurePassword)
- ActionText
ActionText::Content#to_plain_text
- ActiveJob
ActiveJob::Base#perform_now
Google広告
2021-10-11 ~ 2021-10-14にRailsにマージされたPR
Better ActionText plain text output for nested lists by swanson · Pull Request #37976 · rails/rails
【仕様変更】
ネストしたul、olをうまいことインデントを入れて整形できるようになりました。非互換なので ActionText を使っている人は要チェック。しかし、このPRは 15 Dec 2019 に作成されているため、2年近くたってマージされたのですね。
Arel: Add support for FILTER clause (SQL:2003) by Envek · Pull Request #40491 · rails/rails
OK
Arelの機能追加。以下のようにfilterが記述できる。これが実現できるのがすごいな。MySQLはサポート対象外みたい。
Model.all.pluck(
Arel.star.count.as('records_total').to_sql,
Arel.star.count.filter(Model.arel_table[:some_column].not_eq(nil)).as('records_filtered').to_sql,
)
Expand gemspec files within gem directory by chriscz · Pull Request #41934 · rails/rails
OK: generatorの修正
OK
機能追加。しかし insert_all と upsert_all のときにオプションを指定するとタイムスタンプが更新できるのは良い機能ですね。
ちょっと気になったのは https://github.com/rails/rails/pull/43003/files#diff-3f89af7ff219385718b7c0e4635cc4190476349db18f8bf80fb84fa1e7f5e289R82 に TODO が残っています。
# TODO: Consider remaining this method, as it only conditionally extends keys, not always
ということで思わぬエラーに遭遇しそう。エラーに遭遇したら PR を作成するチャンスです!
多くの場合にOK
必要なときのみSELECTを発行する。
多くの場合にOKだけど、こういうのは思わぬときにエラーになるし、もしあればすぐに見つかって修正されるだろう。
clear secure password cache if password is set to
nil
by doits · Pull Request #43378 · rails/rails
【仕様変更】
ActiveRecord(ActiveModel)の属性のpasswordにnilをセットしたとき、修正前はパスワードがクリアされていなかった。キャッシュに残っていた。それをきちんとクリアするようにしている。仕様変更だけど、ナイスな修正!
Bump Rake Pin in Railties by nvick · Pull Request #43398 · rails/rails
OK: Rake が0.13から12.2以上になる。
Treat html suffix in controller translation by rafaelfranca · Pull Request #43415 · rails/rails
I18n.translateのかわりにActiveSupport::HtmlSafeTranslation.translateを使う修正。メッセージカタログに文字を埋め込むときにHTMLがエスケープされるようになる。ナイスな修正だけで思わぬ非互換があるかもしれず、またそれを見つけるのは難しい。影響を受けたとしても、潜在的にセキュリティホールになる箇所が解消されたってことで問題ないとする。
OK: テストの修正
OK: doc
DOCS: Improve ActionText FixtureSet Ruby docs by seanpdoyle · Pull Request #43425 · rails/rails
OK: doc
OK
修正前は、セッションを無効にしているときにCSRFトークンを受け取るとエラーにしていた。しかし、セッションを無効にしていることを判定することが難しく、意図せずエラーとなってしまった。そこで、「セッションを無効にしているときにCSRFトークンを受け取ったかどうか」のチェックをしないようにした。
なお、↑のチェックは Explicitly fail on attempts to write into disabled sessions · Shopify/rails@c1c96a0 で追加されたもの。
チェックしていたものをチェックしないようにしただけなので、バージョンアップへの影響はないでしょう。
わかんない。
これなんだろう。CIで失敗したので修正。修正内容は net-smtp 0.2.2 (先週 ruby 本体に取り込まれたもの) に依存する digest のバージョンを 3.0.1dev にしたというものだった。ActionMailboxを使っていると同じような問題に遭遇するのかな。
【仕様変更】
ActiveJob::Base.set
の設定を perform_now
でも使うようになる。ActiveJob::Base.set
を利用している場合は挙動が変わる。
Raise error when serializing an anonymous class. by VeerpalBrar · Pull Request #43436 · rails/rails
OK
ActiveJobの引数などのシリアライズをするときに無名クラスや無名モジュールだと例外が挙がるようになった。元々エラーになっていたようなので問題ない。
OK: doc
OK: doc
OK
ActiveRecordの不具合修正。
これが問題になるようなコードはさすがにないだろう。
OK: doc
Fix primary_abstract_class with engines by eileencodes · Pull Request #43447 · rails/rails
OK: engineのgeneratorのバグ修正。
【仕様変更】
まずはこれをみてほしい。
comment = post.comments.first
comment.update!(post_id: some_other_post_id)
# comment.post should now return the post with some_other_post_id, but
# since it was inversed it doesn't go stale and this test fails
refute_equal post, comment.post
つまり、あるレコード(post)と関連レコード(post.comments.first)との紐付けを変更する。そのときに関連レコード(comments)から元のレコードを参照する(comment.post)と、紐付けを変更したにもかかわらず、元のレコード(post)を参照できてしまう。
この不具合を修正している。
さすがにこの不具合に依存したコードは少ないだろうけど、思い当たるものはたくさんある。モンキーパッチを仕込んでチェックするとかしないと、影響の有無がわかんないだろうな。
余談: refute_equal
の存在を知らなかった: refute_equal (MiniTest::Assertions) - APIdock
OK: doc
OK: doc
OK: Rails自体のテスト用のseleniumのバージョンを上げただけ。
OK
新しい Rails アプリを生成するときに –css オプションを指定する。そのときに ActionText に関連した css を import するための設定が漏れていたので、 import するように修正している。
Fix Selenium deprecation warnings in CI. by sabulikia · Pull Request #43459 · rails/rails
OK: Rails自体のCI
OK
ActiveRecord.default_timezoneは :local か :utc しか受け付けないため代入時点でチェックするようになった。ナイスな修正です!
OK: doc
ルーティングの設定で wildcard segments を指定できるんだ!?知らなかった。
週刊Railsウォッチ: ServerTimingミドルウェア追加、paramsで数値キーを許可、Railsで多要素認証ほか(20211011前編)|TechRacho by BPS株式会社
Let link_to infer link name from Model#to_s by olivierlacan · Pull Request #42234 · rails/rails
これは便利そう。
Allow permitting numeric params by HParker · Pull Request #42501 · rails/rails
permit book: { authors_attributes: { '1': [ :name ], '0': [ :name, :age_of_death ] } }
↑のように書けるようになるので、いちおう仕様変更。でも既存のコードでこのような指定はしていないだろうから問題ないでしょう。
週刊Railsウォッチ: Ruby 3.1にYJITマージのプロポーザル、Rubyのmagic historyメソッド、JSのPartytownほか(20211012後編)|TechRacho by BPS株式会社
Rails関係の記事はありませんでした。でも気になる記事が満載でした。特に、
は参考になりました。 Basecamp でフランクに localStorage を使っていたのでケースバイケースなんだろうなと感じていましたが、プレゼン資料には「(SPAにおいてセッションIDやトークンの格納場所は) Cookie と localStorageはどちらが安全とは言えず一長一短」とあるため、 localStorage という選択肢もあるのだとあらためて感じました。今後は localStorage を使わないと決めつけるのではなく、脅威が何かを考えて使えるときには使おうと思いました。
今回のおまけ
パーフェクト Ruby on Rails 【増補改訂版】を買いました。
網羅的に Ruby on Rails 6.0 のことが書かれていて、これ一冊でかなりいろいろなことが学べます。CarrierWave しか使ってなかったので ActiveStorage のことは全然知りませんでした。もっと早く買えばよかった。