前回は enum の要素が重複したときの対処方法を記事にしましたが、
それについて、Twitter でコメントをいただきました。

前回の記事で触れた、_prefix: を付ける方法と、
コメントで頂いた _prefix: true or _suffix: trueを付ける方法のそれぞれで、
どういった違いがあるか調べてみました。

エラーになるコード

まずは要素が重複して、エラーになるコードの例です。

class Travel < ApplicationRecord  
    enum from: { tokyo: 0, osaka: 1, okinawa: 2 }  
    enum destination: { hokkaido: 0, aichi: 1, okinawa: 2 }  
end

当然これはエラーになります。
enum destination:okinawaが重複しています。

ArgumentError: You tried to define an enum named "destination" on the model "Travel", but this will generate a instance method "okinawa?", which is already defined by another enum.

_prefix を付与する

前回の記事で書いたとおり、次のように _prefix を付与します。

class Travel < ApplicationRecord  
    enum from: { tokyo: 0, osaka: 1, okinawa: 2 }, _prefix: :from  
    enum destination: { hokkaido: 0, aichi: 1, okinawa: 2 }, _prefix: :dest  
end

こんな感じで登録しました。

irb(main):012:0> t = Travel.first  
  Travel Load (0.7ms)  SELECT  "travels".* FROM "travels" ORDER BY "travels"."id" ASC LIMIT ?  [["LIMIT", 1]]  
=> #<Travel id: 1, from: "tokyo", destination: "aichi", created_at: "2019-03-15 07:05:22", updated_at: "2019-03-15 07:05:22">

任意のprefixを付与した場合、例えば値の真偽値を取得する場合は、次のような書き方になります。

irb(main):013:0> t.dest_aichi?  
=> true  
irb(main):014:0> t.from_tokyo?  
=> true  
irb(main):015:0> t.from_osaka?  
=> false

prefix(接頭辞)に、fromdestをつけたので、<prefixの値>_<要素名>? で真偽値を取得できました。

_prefix: true を付与する

今回の例では、prefix(接頭辞)に、fromdest つけても、
英文法的に極端にわかりにくくはありませんでしたが、
Twitter のコメントであったように、prefix に true をつけるとどうなるでしょうか。

irb(main):003:0> t.from_tokyo?  
=> true  
irb(main):004:0> t.destination_aichi?  
=> true  
irb(main):005:0> t.from_osaka?  
=> false

True をつけると、<prefixの値>_<要素名>? だったのが、<カラム名>_<要素名>? になりました。

_suffix: true を付与する

Suffix(接尾辞) を true にすると、このようになります。

irb(main):002:0> t.tokyo_from?  
=> true  
irb(main):003:0> t.aichi_destination?  
=> true  
irb(main):004:0> t.osaka_from?  
=> false

<要素名>_<カラム名>? になり、カラム名が後ろに付きます。
今回のカラム名では英文法的に違和感があるので、Prefix を使うほうが良いかなと思いました。

カラム名によっては、Prefix あるいは Suffixに任意の値ではなく、
True をつけたほうが、構文的に統一感があり、真偽値などを取得する際に、
違和感のない英文法で書けることがわかりました。

# prefix に任意の値を設定  
class Travel < ApplicationRecord  
    enum from: { tokyo: 0, osaka: 1, okinawa: 2 }, _prefix: :from  
    enum destination: { hokkaido: 0, aichi: 1, okinawa: 2 }, _prefix: :dest  
end
# prefix に true を設定  
class Travel < ApplicationRecord  
  enum from: { tokyo: 0, osaka: 1, okinawa: 2 }, _prefix: true  
  enum destination: { hokkaido: 0, aichi: 1, okinawa: 2 }, _prefix: true  
end

まとめ

例示したコードがあまりいい例ではありませんでしたが、
prefix、suffix に true、任意の値をそれぞれ付与したときの動作が理解できました。
読みやすいコードを意識しながら、コーディングするのはなかなか難しいですが、
コツコツ続けていけたらと思います。

関連記事

この記事へのコメント

まだコメントはありません
1
@toyocyの技術ブログ
1
このエントリーをはてなブックマークに追加