【Rails】enum型で複数の同じenum名を定義する
こんにちは。
標題の通り、enum型で複数の同じenum名を定義した際に発生するエラーを回避する方法を
学習したので、アウトプットしていきます。
尚、指摘箇所がございましたら
ご教授いただけますと幸いです。
前提
前提として、ジャンルテーブルを作成済みでカラムにenum型を定義しています。
*簡略化のため、一部省略しております。
class Genre < ApplicationRecord
belongs_to :recipe
validates :staple_food, :main_dish, presence: true
enum staple_food: {
others: 0,
rice: 1,
bread: 2,
noodles: 3
}
enum main_dish: {
others: 0,
meat: 1,
fish: 2,
egg: 3,
soybean: 4
}
end
同じenum名を定義するとどうなるか?
enum staple_food: {
others: 0,
...
}
enum main_dish: {
others: 0,
...
}
では、上記のようにothers
という名前が重複してしまうとどうなるのでしょうか。
Genre.create(recipe_id: 4, staple_food: 3, main_dish: 4)
~ `raise_conflict_error': You tried to define an enum named "staple_food" on the model "Genre", but this will generate a instance method "others?", which is already defined by another enum. (ArgumentError)
こうですね。
「"others?"というインスタンスメソッドを作りたいんだけど、もうすでに他のenum型によって定義されているよ」と怒られてしまいます。
回避方法
Railsではちゃんと同じ名前で定義ができるように整備されています。
You can use the :prefix or :suffix options when you need to define multiple enums with same values. If the passed value is true, the methods are prefixed/suffixed with the name of the enum. It is also possible to supply a custom value:
ActiveRecord::Enum
「同じ値で複数のenumを定義する必要があるときは:prefix
もしくは:suffix
を使えるよ」と教えてくれてます。
:prefix
は接頭辞という意味で、例えば「ご相談」の「ご」がそれにあたります。
:suffix
は接尾辞という意味で、例えば「彼ら」の「ら」がそれにあたります。
今回は:prefix
で実装していきます。
class Genre < ApplicationRecord
belongs_to :recipe
validates :staple_food, :main_dish, presence: true
enum staple_food: {
others: 0,
rice: 1,
bread: 2,
noodles: 3
+ }, _prefix: true
enum main_dish: {
others: 0,
meat: 1,
fish: 2,
egg: 3,
soybean: 4
+ }, _prefix: true
end
これで再度データを作成していきます。
Genre.create(recipe_id: 4, staple_food: 3, main_dish: 4)
TRANSACTION (0.1ms) BEGIN
TRANSACTION (0.4ms) SAVEPOINT active_record_1
Recipe Load (1.0ms) SELECT `recipes`.* FROM `recipes` WHERE `recipes`.`id` = 4 LIMIT 1
Genre Create (0.8ms) INSERT INTO `genres` (`recipe_id`, `staple_food`, `main_dish`, `created_at`, `updated_at`) VALUES (4, 3, 4, ***)
TRANSACTION (0.1ms) RELEASE SAVEPOINT active_record_1
こうですね。ちゃんとデータを作成することができました!
最後までお読みいただきありがとうございます!
Discussion