43
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ActiveRecord::Enum の注意点

Last updated at Posted at 2014-07-24

背景

Rails 4.1 より ActiveRecord::Enum が利用可能となりました。
これにより以下の様な記述が可能となります。

class User < ActiveRecord::Base

  enum role: [:general, :admin]

  ...
end

# role が admin なユーザを取得する
user = User.admin.first!
 
# admin かどうか
user.admin?
 
# role を確認
user.role # => "general"
 
# role を admin に変更
user.admin!
 
# role の取りうる値を確認
User.roles # => {"general"=>0, "admin"=>1}

これまで区分値として保持していた値が簡単に管理できるようになってハッピーです。

注意点

とっても便利な Active::Enum ですがいくつか注意点があります

  1. 要素を追加する場合は末尾にアペンドすること

ActiveRecord::Enum により定義された値は、内部的には 0, 1, 2, 3... という数値型に変換されます。新しく要素を追加する場合には末尾にアペンドするようにしましょう。

変更前

status に 新しく :in_review を追加したい

class Article < ActiveRecord::Base

  # => 0-:new, 1-:approved, 2-:rejected 3-:in_review
  enum status: [:new, :approved, :rejected] 
  ...
end

悪い例

配列の途中に新しい要素を追加すると、以降のマッピングが変わってしまい、既存データとの整合性が取れなくなってしまいます。

class Article < ActiveRecord::Base

  # 既存データとの整合性が取れなくなってしまう!!
  # => 0-:new, 1-:approved, 2-:in_review, 3-:rejected 4-:in_review
  enum status: [:new, :in_review, :approved, :rejected] 
  ...
end

良い例

新しく要素を追加するときは配列の末尾にすることで、既存データとの整合性が取れます。

class Article < ActiveRecord::Base

  # => 0-:new, 1-:approved, 2-:rejected, 3-:in_review, 4-:in_review
  enum status: [:new, :approved, :rejected, :in_review] 
  ...
end
  1. 同じ名前を同じクラス内で利用しないこと

複数の enum フィールドに同じ名前を使わないようにしましょう。

class Article < ActiveRecord::Base
  enum status: [:new, :approved, :rejected] 
  enum category: [:lifehack, :biz, :animals, :new] # :new が重複!
  ...
end
  1. scope で利用する場合には数値を利用すること

scope 内にて検索条件として利用する場合にはシンボルではなく数値を利用しましょう。

class Article < ActiveRecord::Base
  enum status: [:new, :approved, :rejected] 

  scope :hidden, -> { where('status <> ? AND status <> ?', STATUS[:new], STATUS[:rejected]) }
end

(番外)ユーザ向けの入出力項目としては利用しないこと

現在のところ ActiveRecord::Enum は内部処理のみで利用し、form での入力項目や画面での出力項目として利用することは意図していないようです。

参考: Rails4 - ActiveRecord::Enum の使いドコロ - Qiita

回避方法はいくつかありますが、頭の片隅においておくとよいかと思います。

43
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?