Edited at

便利なenum 初心者→中級者へのSTEP5/25


便利なenum

はじめに

前回の記事でenumが出てきましたね。てな訳でenumです。僕もあんまり触ったとこないです。そんなenumの何が便利なのか調べていきましょう。


enumの活用例

enumとは簡単にいうと、 Railsのintegerクラスの属性の整数値にテキストでアクセスできる様にしてくれるものです。


schema.rb

ActiveRecord::Schema.define(version: 20181202084037) do

create_table "users", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "email"
t.string "user_id"
t.integer "status"
t.text "discription"
end

end


上のUser.rbにてstatus属性で会員の状態を判断する場合。enumを使わない場合。数字で判断する羽目になり、可読性が悪いです。


member_status.rb

  if @user.status == 0

#通常会員の処理
elsif @user.status == 1
#プレミアム会員の処理
end


コメントがないとなんの処理をしているかわかりませんよね?

ではenumを使ってみましょう。

まずUser.rbにてstatus属性をenumとして定義します。


User.rb

class User < ApplicationRecord

enum status: {
normal: 0, #通常会員
premium: 1, #プレミアム会員
}

end


これでstatus属性にテキストのnormalpremiumでアクセスできます。


member_status.rb

  if @user.normal?

#通常会員の処理
elsif @user.premium?
#プレミアム会員の処理
end


これなら、コードを見るだけでここでなんの処理が書かれているかわかりますよね!


enumで使えるメソッド


User.rb

class User < ApplicationRecord

enum status: {
normal: 0, #通常会員
premium: 1, #プレミアム会員
}
end

user.premium! # => userのstatusをpremiumでupdateする
user.premium? # => true
user.status # => "premium"


上記3つのメソッドは基本的によく使うであろうもの、下記のはある状況下で必要なもの。


User.rb

class User < ApplicationRecord

enum course_status: {
normal: 0, #通常会員コース
premium: 1, #プレミアム会員コース
}, _suffix: true

enum age_group: {
normal: 0, #通常
minority: 1, #未成年
}, _prefix: :age_group
end

user.normal_course_status! # => userのcourse_statusをnormalでupdateする
user.normal_course_status? # => true

user.age_group_normal! # => userのage_groupをnormalでupdateする
user.age_group_normal? # => true


上の例ではcourse_statusage_groupnormalが被っています。その場合は_suffix:_prefixを用いて接頭辞・接尾辞を指定できるようにします。

_suffix:が接尾辞、_prefixが接頭辞です。


enumでの注意点

明示的に対応する整数値を指定しないと、識別子のリストの先頭から順に0,1,...と対応づけられていくので、以下の様に明示的に記載してない場合、例えばcatを削除する場合、kamoの対応する整数値が3から2になってしまいます。しかしDBに保存された値は3なので、対応する識別子がなくnillになってしまいます。


User.rb

class User < ApplicationRecord

enum course_status: [pig:, dog:, cat:, kamo:]
end

上記から猫ちゃんを削除する時、その後、明示的に元の整数を指定してあげましょう。


User.rb

class User < ApplicationRecord

enum course_status: {pig: 0, dog: 1, kamo: 3}
end

というより最初から明示的に書きましょう。


まとめ

いやあ便利、非常にコードが見やすくなります。是非使っていきましょう。

明日はscopeとやらについて掘り下げるンゴ


参考にしたの

ActiveRecord::Enum

https://api.rubyonrails.org/v5.2.1/classes/ActiveRecord/Enum.html

ActiveRecordのenumで気をつけたい3つのポイント

https://tech.misoca.jp/entry/2015/08/10/132419