🚃
Rails 8ではenumで非推奨になっていた書き方が使用禁止になった話
はじめに
Rails 7.2 で enum
のキーワード引数を使った定義が非推奨になり、Rails 8 ではそれが完全に禁止されました。本記事では、この変更の詳細と背景、移行の方法について解説します。
対象読者
- Rails 開発者
- 既存コードをメンテナンスしているエンジニア
- Rails 8 へのアップデートを検討しているチーム
Rails 7.2以前の(非推奨の)書き方
class Conversation < ApplicationRecord
enum status: { active: 0, archived: 1 }, _prefix: true
end
Rails 7.2 では、上記のような「キーワード引数を使用した列挙型の定義」が非推奨になりました。
こちらのテックブログにて、enumのコード解説をされてました。
enumコードの確認def enum(name = nil, values = nil, **options)
if name
values, options = options, {} unless values
return _enum(name, values, **options)
end
definitions = options.slice!(:_prefix, :_suffix, :_scopes, :_default, :_instance_methods)
options.transform_keys! { |key| :"#{key[1..-1]}" }
definitions.each { |name, values| _enum(name, values, **options) }
ActiveRecord.deprecator.warn(<<~MSG)
Defining enums with keyword arguments is deprecated and will be removed
in Rails 7.3. Positional arguments should be used instead:
#{definitions.map { |name, values| "enum :#{name}, #{values}" }.join("\n")}
MSG
end
第一引数が位置引数かキーワード引数かで処理が分かれていたのですね。
コードを見るに、7.3でも完全廃止になる可能性が高そうですね。
Rails 8での変更: キーワード引数の完全廃止
Rails 8 では、非推奨だったキーワード引数を使う定義が 完全に禁止 され、エラーとなります。
kamal-rails(dev)> user = User.new
app/models/user.rb:2:in '<class:User>': wrong number of arguments (given 0, expected 1..2) (ArgumentError)
from app/models/user.rb:1:in '<main>'
from (kamal-rails):29:in '<main>'
推奨される書き方
非推奨の書き方に代わり、以下の形式に変更しましょう
class Conversation < ApplicationRecord
enum :status, { active: 0, archived: 1 }, prefix: true
end
今後は「第一引数に位置引数を設定する」で揃えましょう!!
公式を確認する
integerカラムでenumを使用する場合は下記のように書くことができます。
class Conversation < ApplicationRecord
enum :status, [ :active, :archived ]
end
便利ですね。
もちろん、ハッシュを使って、属性とデータベースの整数の関係を明示的にマッピングすることもできます。
class Conversation < ApplicationRecord
enum :status, active: 0, archived: 1
end
ちなみにstringカラムとしenumを使用する場合は下記のように書くことができます。
class Conversation < ApplicationRecord
enum :status, active: "active", archived: "archived"
end
公式でも言われていますが、「データベースのクエリが遅くなる可能性が高いことに注意してください」とのこと。
Discussion