2
3

More than 3 years have passed since last update.

ActiveRecordのEnumの取り扱い方

Last updated at Posted at 2019-03-11

概要

ActiveRecordを継承したモデルへの値の格納の仕方や、値を入力した際にどのバリデーションに反応したのか調べた

前提条件

Rails: 5.2
Ruby: 2.6.1

本題

サンプルのユーザテーブルの定義

create_table :users do |t|
  t.string :name
  t.integer :state
  t.timestamps
end

ユーザモデルの定義

nameの空文字チェックのバリエーションがある

class User < ApplicationRecord
  validates :name, presence: true
  enum state: { show: 0, hide: 1 }
end

モデルを一つ取得し、これをもとに説明する

> u = User.first
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 2, name: "テスト1", created_at: "2019-01-29 03:56:08", updated_at: "2019-03-11 02:52:09", state: "hide">

stateを単純に出力すると、DBに格納されている数値ではなく、enumで定義した文字列が表示される

> u.state
=> "hide"

代入方法

enumで定義したシンボルでも、文字列でも、DBに実際に格納される数値でも代入できる

シンボルの場合

u.state = :hide
=> :hide
irb(main):038:0> u.state
=> "hide"

文字列の場合

u.state = "show"
=> "show"
irb(main):046:0> u.state
=> "show"

数値の場合

> u.state = 0
=> 0
> u.state
=> "show"

定義外の値を代入すると

enumで定義した範囲外の数値を代入しようとするとエラーになる

> u.state = "show2"
ArgumentError ('show2' is not a valid state)

irb(main):047:0> u.state = "show2"
Traceback (most recent call last):
        1: from (irb):47
ArgumentError ('show2' is not a valid state)

> u.state = :show2
ArgumentError ('show2' is not a valid state)

> u.state = 2
ArgumentError ('2' is not a valid state)

格納されている実際の値を参照する

デバッグやテストのときなどu.stateとすると実際にどの値が格納されているか確認したい場合は
read_attribute_before_type_cast属性名_before_type_castを使う

> u.state
=> "hide"

 u.read_attribute_before_type_cast(:state)
=> 1
irb(main):070:0> u.state_before_type_cast
=> 1
2
3
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
2
3