Close icon
2017月11日13日

ActiveRecordのenum

ActiveRecordのenumが便利です。
enumを使用することで値の判定などわかりやすいコードが書けるようになります。
http://api.rubyonrails.org/v5.1/classes/ActiveRecord/Enum.html
例えば、Spotモデルに下書き(draft)と公開(published)の状態をもつステータスを追加するとします。

Spotモデルにstatusカラムを追加するマイグレーションを作成

rails g migration add_status_to_spot status:integer

Spotモデルにenumを追加

class Spot < ApplicationRecord
  belongs_to :prefecture
  belongs_to :area

  has_many :spot_photos
  has_many :spot_galleries
  validates :title, presence: true
  validates :prefecture_id, presence: true
  validates :area_id, presence: true
  validates :latitude, numericality: true
  validates :longitude, numericality: true

  enum status: { draft: 0, published: 1}
end

statusの値をenumで定義します。
statusが0の場合はdraft、1の場合はpublishedにします。

statusの判定

rails consoleで動作を確認してみます。

$ rails c
Running via Spring preloader in process 67570
Loading development environment (Rails 5.0.5)
irb(main):001:0> spot = Spot.new
=> #<Spot id: nil, title: nil, prefecture_id: nil, address: nil, overview: nil, des
cription: nil, area_id: nil, created_at: nil, updated_at: nil, url: nil, title_kana
: nil, address_description: nil, latitude: nil, longitude: nil, category_id: nil, i
dentifier: nil, status: nil>
irb(main):002:0>

irb(main):003:0* spot.status = 0
=> 0
irb(main):004:0> spot.draft?
=> true
irb(main):005:0> spot.published?
=> false

この例では、soptのstatusに0を代入しています。
この場合、spot.draft? でstatusの値が0なのか、spot.published? でststusの値が1なのかを判定できるようになります。
ststusに0を代入しているので、spot.draft? はtrueになっています。

次にspot.statusに1を代入してみます。

irb(main):017:0* spot.status = 1
=> 1
irb(main):018:0> spot.draft?
=> false
irb(main):019:0> spot.published?
=> true

spot.draft?はfalseになり、spot.published?はtrueになります。
このようにstatusの状態を判定します。

statusのハッシュ

下記のように属性名の複数形でenumで定義したハッシュが取得できます。

irb(main):032:0* Spot.statuses
=> {"draft"=>0, "published"=>1}

statusは数値ではなく文字列を返す

Spotのstatusはintegerですが、下記のようにspot.statusは文字列を返します。

irb(main):034:0* spot.status = 0
=> 0
irb(main):035:0> spot.status
=> "draft"
irb(main):036:0> spot.status = 1
=> 1
irb(main):037:0> spot.status
=> "published"
irb(main):038:0> spot.status.class
=> String

enumで指定した値以外は設定できない

enumで定義した値以外を代入すると例外が発生します。

irb(main):039:0> spot.status = 2
ArgumentError: '2' is not a valid status



アトトックラボとは

株式会社アトトックメンバー が技術の話、デザインの話、キャラクターの話、ときどき脱線してガジェットの話やライフハックの話など好きなことを書いています。


連載記事


最近の記事


タグ