読者です 読者をやめる 読者になる 読者になる

カッパでも分かるiOSアプリゲーム開発

カッパがひたすらゲーム制作に関することを書くブログです。Railsに関するTipsもたまにまとめてます。

ActiveRecord Enum のメリット、デメリットについて調べてみた→コードが凄く短くなった

スポンサードリンク

f:id:InvokeTwoA:20151106031914j:plain

ActiveRecord の Enum とはなんぞや

ドキュメント

ActiveRecord::Enum

使うメリットは?

  • DBでよくあるステータスが 0: 準備中 1: 提出完了 2: キャンセル みたいな定義をするのに便利(0,1,2のようなマジックナンバーを使わないで済む)
class User < ActiveRecord::Base
  enum status: %i(normal admin retire)
end

これをすると 0: normal 1: admin 2: retire という風になる。
また、下記のような関数が自動で用意されるため、不要なscopeを定義しないで済む。

> User.normal
SELECT `users`.* FROM `users`  WHERE `users`.`status` = 'normal'

> User.admin
SELECT `users`.* FROM `users`  WHERE `users`.`status` = 'admin'

他にもUser.normal? とかすればステータスが normal かどうかを簡単に確認できたりする
一番便利なのが

User.normal!

とすれば ステータスを normal に変更できる。

  • また、enum で定義した値以外を無効にできるのも大きなメリット。上記の例だと 99 などの未定義なステータスで更新しようとするとエラーになる。
  • ステータス一覧を取得するのが容易
User.statuses
-> {"normal"=>0, "admin"=> 1, "retire"=>2 }

使うデメリットは?

  • まだ扱いに慣れてない人が多いせいか、運用をする上で使用ミスが見受けられる

例えば status に新しく何かを追加するとき、左に何かを追加したら全ての値がずれてしまう。

class User < ActiveRecord::Base
  enum status: %i(normal admin retire hoge)
end

これならば 0:normal 1:admin 2:retire 3:hoge で問題ないけれど

class User < ActiveRecord::Base
  enum status: %i(hoge normal admin retire)
end
  • これだと 0:hoge 1:normal 2:admin 3:retire となり、全ての値が1ずつずれてしまう。
  • 決して値を左から追加しないこと。或いは対応する値を明記しておくと良い。
class User < ActiveRecord::Base
  enum status: { hoge: 3, normal: 0, admin: 1, retire: 2}
end

結論

enum を導入したらコードがかなり短くなった

before
if status == 'unsubmitted' || status == 'disabled'
  status = 'done'
  save!
end
after
if unsubmitted? || disabled?
  done!
end

f:id:InvokeTwoA:20151023183618p:plain「デメリットよりもメリットの方が圧倒的に多いのでオススメ」