カレーの恩返し

おいしいのでオススメ。

Rails7.1からcolumn,enum名に使えない名前が増える可能性が高いので注意

3行まとめ

  • Rails 7.1 から dup, freeze, hash, object_id, class, clone, frozen は column 名や enum の種類として使えなくなる可能性が高い
  • 該当 column を持つ Model の initialize で ActiveRecord::DangerousAttributeError が発生する
  • 各位そういった名前を使わない、rename するなど身構えておきましょう

起きていた問題

会社の Rails アプリケーションに対して rails/rails の main branch を使ってテストを走らせていたら以下のようなエラーを数多く見かけるようになった。

ActiveRecord::DangerousAttributeError:
  object_id is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
# /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/decorator/new_constructor.rb:9:in `new'
# /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/decorator.rb:16:in `send'
...

どうやらテストの前準備のレコード作成でコケている様子。(具体的には factory_botcreate(:xxxx)

object_id...?なんのことだ...?と思って調べてたら作成対象の model の association に object_id という column を持つ model が存在することが分かった。 ActiveRecord によって object_id メソッドを上書きされるの危険そうだなと思いつつ、なぜ Rails 7.0 ではエラーにならず Rails 7.1 で問題になるのか分からなかったので調べてみて原因を特定した。

github.com

変更が入ったのは上記 PR。column 名に hash という名前を使うと ActiveRecordObject#hash をオーバーライドしてしまい、問題が発生していた。 その問題と今後発生しそうな問題を防ぐために Object クラスでオーバーライドされると困りやすい dup, freeze, hash, object_id, class, clone を AR が定義しようとするとエラーにする変更を加えたとのこと。

github.com

後続の変更で frozen? も使えなくなっている。AR は boolean の column に対しては自動的に ? 付きのメソッドを定義するので boolean の frozen column も使えなくなってそう。
これは column だけではなく enum によるメソッド定義でも同様なので enum の種類に frozen を使っているアプリケーションも書き換えが必要になるんじゃないかな。

まだ Rails 7.1 はリリースされていないので確定ではないものの、主張としては真っ当なのでそのまま入りそうな気がしている。 上記に該当するアプリケーションをお持ちの方は身構えておくと良いのではないでしょうか。

感想

git bisect コマンド初めて使ったんですが、これ便利ですね...