lulu

【Rails】Modelにenumを追加して、カラムの値を制限する方法

やること

RailsのModelにenumを追加して、カラムに入力される値を制限する方法を解説します。また、scopeとしての使い方も解説します。

ver

  • ruby 2.5.1
  • Rails 6.0.3

Modelにenumを追加する

role(integer)というカラムに入力される値は、0,1,2に制限する

class User < ApplicationRecord
  enum role: {
    admin: 0,
    creator: 1,
    tester: 2
  }
end

実験

irb(main):001:0> User.create(name: "管理者", role: 0);
   (0.7ms)  SELECT sqlite_version(*)
   (0.1ms)  begin transaction
  User Create (0.5ms)  INSERT INTO "users" ("name", "created_at", "updated_at", "role") VALUES (?, ?, ?, ?)  [["name", "管理者"], ["created_at", "2021-06-12 01:24:46.565057"], ["updated_at", "2021-06-12 01:24:46.565057"], ["role", 0]]
   (1.3ms)  commit transaction
=> #<User id: 10, age: nil, name: "管理者", created_at: "2021-06-12 01:24:46", updated_at: "2021-06-12 01:24:46", role: "admin">
irb(main):002:0> User.create(name: "例外", role: 3);
Traceback (most recent call last):
        1: from (irb):2
ArgumentError ('3' is not a valid role)

このように、0,1,2以外の数字をsaveしようとすると、エラーが発生する

scopeとしての使い方

enumで設定した値はscopeとして利用することもできる

irb(main):001:0> User.admin
   (0.7ms)  SELECT sqlite_version(*)
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."role" = ? LIMIT ?  [["role", 0], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 10, age: nil, name: "管理者", created_at: "2021-06-12 01:24:46", updated_at: "2021-06-12 01:24:46", role: "admin">]>

このように、roleのadminを指定することで、admin roleをもつUserを絞り込んで検索することができる