DEV Community

@kon_yu
@kon_yu

Posted on

How to handle Enum in ActiveRecord

Overview

How to store values in models that inherit from ActiveRecord, and which validations are responded to when you enter a value.

Prerequisites.

Rails: 5.2
Ruby: 2.6.1

main topic.

Sample User Table Definitions

create_table :users do |t|
  t.string :name
  t.integer :state
  t.timestamps
end
Enter fullscreen mode Exit fullscreen mode

Defining the user model

There's a variation of the empty character check for name.

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

Take one model and explain it based on it.

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

If you simply output state, you will see the string defined by enum instead of the number stored in the DB.

> u.state.
=> "hide"
Enter fullscreen mode Exit fullscreen mode

Assignment Method

You can substitute symbols defined by enum, strings, or numbers actually stored in the DB.

In the case of symbols

u.state = :hide
=> :hide
irb(main):038:0> u.state
=> "hide"
Enter fullscreen mode Exit fullscreen mode

In the case of a string

u.state = "show"
=> "show"
irb(main):046:0> u.state
=> "show"
Enter fullscreen mode Exit fullscreen mode

In the case of numbers

> u.state = 0
=> 0
> u.state.
=> "show"
Enter fullscreen mode Exit fullscreen mode

Assigning an undefined value

If you try to assign a number outside the range defined by enum, you get an error.

> 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)
Enter fullscreen mode Exit fullscreen mode

Refer to the actual stored value

You can use u.state for debugging or testing to check which value is actually stored.
Use read_attribute_before_type_cast or attribute_name_before_type_cast.

> u.state.
=> "hide"

 u.read_attribute_before_type_cast(:state)
=> 1
irb(main):070:0> u.state_before_type_cast
=> 1
Enter fullscreen mode Exit fullscreen mode

Top comments (0)