LoginSignup
0
1

More than 1 year has passed since last update.

【WIP】ActiveRecord::Enum

Last updated at Posted at 2022-08-22

Enum is 何

  • enumは列挙型

定義例

class Book < ApplicationRecord
  enum sales_status: {
    reservation: 0, # 予約受付中
    now_on_sale: 1, # 発売中
    end_of_print: 2, # 販売終了
  }
end

保存のされ方

  • シンボル、文字列、数値を渡しても戻り値が"now_on_sale"と表現される
irb(main):001:0> Book.create(sales_status: :now_on_sale)
=> #<Book id: 1, sale_status: "now_on_sale">

irb(main):002:0> Book.create(sales_status: "now_on_sale")
=> #<Book id: 2, sale_status: "now_on_sale">

irb(main):003:0> Book.create(sales_status: 1)
=> #<Book id: 3, sale_status: "now_on_sale">

状態の確認

  • メソッドで状態を確認できる
irb(main):001:0> book = Book.last

irb(main):002:0> book.now_on_sale?
=> true

irb(main):003:0> book.end_of_print?
=> false
  • enumの値の末尾に「!」付きのメソッドを使うと、そのenumの値へ更新できる。(DB上にも反映)
irb(main):004:0> book.end_of_print!

irb(main):005:0> book.end_of_print?
=> true

irb(main):006:0> book.now_on_sale?
=> false
  • 直接参照すると文字列の値が取得可能
irb(main):007:0> book.sale_status # 定義された値
=> "end_of_print"

irb(main):008:0> book.sales_status_before_type_cast # DBに保存されている実際の値
=> 
  • 定義の確認
irb(main):009:0> Book.sale_statuses
=> {"resercation"=>0, "now_on_sale"=>1, "end_of_print"=>2}
  • 未定義の値を保存しようとするとArgumentErrorが発生
irb(main):010:0> Book.create(sale_status: hogehoge) 
ArgumentError('hogehoge' is not a valid sales_status)
  • scopeとしても利用可
irb(main):011:0> Book.now_on_sale
 Book Load (0.4ms) SELECT "books".* FROM "books"
 WHERE "books". "sales_status" = ?
 LIMIT ? [["sales_status", 1], ["LIMIT", 11]]

irb(main):012:0> Book.not_now_on_sale
 Book Load (0.4ms) SELECT "books".* FROM "books"
 WHERE "books". "sales_status" != ?
 LIMIT ? [["sales_status", 1], ["LIMIT", 11]]
0
1
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
0
1