はじめに
現在、プログラミングスクールRUNTEQに通う初学者です。
開発中のエラー解決の一助になればという想いで記事を書いてみました。
まだまだ知識不足な点も多く、記事内容に間違いや改善点があれば教えていただけると幸いです。
記事を書くことになったそもそもの発端
「パーフェクト Ruby on Rails」を自分の理解度も確認しながら、
Rails8.0.1(書籍の推薦環境はRails6.0.3)でチャレンジしながらやっていたところ、下記でつまづきました。
class Book < ApplicationRecord
# 〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜
enum sales_status: {
reservation: 0,
now_on_sale: 1,
end_of_print: 2,
}
end
上記を記載の後に、bin/rails c
をターミナルで実行。
Book.create
したところ、引数が違うとのエラーが出現。
book-admin(dev)* Book.create(
book-admin(dev)* name: "enum Book 1",
book-admin(dev)* sales_status: :now_on_sale,
book-admin(dev)* publisher: Publisher.find(1),
book-admin(dev)* price: 100
book-admin(dev)> )
app/models/book.rb:32:in '<class:Book>': wrong number of arguments (given 0, expected 1..2) (ArgumentError)
from app/models/book.rb:1:in '<main>'
from (book-admin):37:in '<main>'
上記は、試行錯誤の後に無事解決できたのですが、 そもそも今までのenumの書き方が、どうやらRailsのアップデートで変わっていたみたいなので自分用メモも兼ねて、ココに記します。
実行環境
ruby 3.4.1
rails 8.0.1
結論
下記のように直したら無事にcreate
できました。
class Book < ApplicationRecord
# 〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜
enum :sales_status, { # <- コロン位置を変更してシンボルにする
reservation: 0,
now_on_sale: 1,
end_of_print: 2,
}
end
なぜ?
どうやらrails8.0へのアップデート変わっているようです。
以前のバージョンではこう書いてもOKでした。
(※「enum」で検索するとこのバージョンで解説している記事が多い。各サイトの実行環境によるものなので要チェック!)
class Book < ApplicationRecord
# 〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜
enum sales_status: { # <- カラム名(または属性名)として記載
reservation: 0,
now_on_sale: 1,
end_of_print: 2,
}
end
しかし、Rails 7.2 で 「キーワード引数の使用による列挙型の定義は非推奨」 となり警告が表示されるようになり、Rails8.0以降は、第1引数として渡す必要がある。
class Book < ApplicationRecord
# 〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜
enum :sales_status, { # <- 第一引数として渡す必要がある
reservation: 0,
now_on_sale: 1,
end_of_print: 2,
}
end
参考記事)
Rails 7.2のenum非推奨警告を回避する方法と修正ポイント
ここからは仮説
上記で、 「キーワード引数の使用による列挙型の定義は非推奨」 と書きましたが、なんで非推薦になったのか?と疑問を持ち、色々調べていったところ、下記の記事にたどり着きました。
ここからはおそらくなのですが、
Ruby 2.0以降にある、キーワード引数をハッシュオブジェクトに自動変換できるは欠陥がある
↓
Ruby 3.0で、普通の引数(特にハッシュオブジェクト)とキーワード引数を完全に分離
↓
Railsにも影響。キーワード引数の使用による列挙型の定義は非推奨へ。
・・・なのかなと。間違いあればご指摘いただけますと幸いです。
参考記事)
サンプルコードでわかる!Ruby 2.7の主な新機能と変更点 Part 2 - キーワード引数に関する仕様変更