Skip to content
GitLab
    • Explore Projects Groups Snippets
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • T torque-postgresql
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 6
    • Issues 6
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 1
    • Merge requests 1
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Carlos
  • torque-postgresql
  • Wiki
  • Enum
Last edited by Carlos 3 years ago
Page history
This is an old version of this page. You can view the most recent version or browse the history.

Enum

Enum type manager. It creates a separated class to hold each enum set that can be used by multiple models, it also keeps the database data consistent. The enum type is known to have a better performance against string- and integer-like enums. PostgreSQL Docs

How it works

Migration

First you have to create the enum during your migration, since it's the database that holds the list of possible values.

create_enum :roles, %i(visitor manager admin)

Some other examples are:

# ['status_foo', 'status_bar']
create_enum :status, %i(foo bar), prefix: true
# 'foo_tst', 'bar_tst']
create_enum :status, %i(foo bar), suffix: 'tst'

You can also manage this type along other migrations, renaming, adding values, or deleting it.

# Rename enum by renaming the type it represents
rename_type :status, :content_status

# Adding values
add_enum_values :status, %i(baz qux)                      # To the end of the list
add_enum_values :status, %i(baz qux), prepend: true       # At the beginning of the list
add_enum_values :status, %i(baz qux), after: 'foo'        # After a certain value
add_enum_values :status, %i(baz qux), before: 'foo'       # Before a certain value
add_enum_values :status, %i(baz qux), prefix: true        # With type name as prefix
add_enum_values :status, %i(baz qux), suffix: 'tst'       # With a specific suffix

# Deleting an enum by dropping the type it represents
drop_type :status

Once you've created the type, you can use while creating your table in three ways

create_table :users do |t|
  t.string :name
  t.role :role                            # Uses the type of the column, since enum is a type
  t.enum :status                          # Figures the type name from the column name
  t.enum :last_status, subtype: :status   # Explicit tells the type to be used
end

The type class

Each enum type that is loaded from the database will have it's own class type of value, created under the enum.namespace namespace.

Enum::Roles

# You can get a representative value from there
Enum::Roles.admin

# Or you can get the list of values
Enum::Roles.values

# Allows you to iterate over the values direct from the class
Enum::Roles.each do |role|
  puts role
end

# You can use index-based reference of a value
Enum::Roles.new(0)       # #<Enum::Roles "visitor">
Enum::Roles.admin.to_i   # 2

Models

If you kept the enum.initializer setting as false, you have to go to each of your models and enable the functionality for each enum type of field. You don't need to provide the values since they will be loaded from the database. The method name is defined on enum.base_method.

# models/user.rb
class User < ActiveRecord::Base
  enum :role, :status
end

You are able to access the list of values trough the class that holds the enum:

User.roles

You can set the column value from String, Symbol, and Integer:

user = User.new
user.role = 'admin'    # #<Enum::Roles "admin">
user.role = :manager   # #<Enum::Roles "manager">
user.role = 0          # #<Enum::Roles "visitor">

This allows you to compare values, or make questions about it:

other_user = User.new(role: :manager)
user = User.new(role: :manager)
user.role > :admin               # false
user.role == 1                   # true
user.role >= other_user.role     # true
user.role.manager?               # true
user.visitor?                    # false

The bang! methods are controlled by the enum.save_on_bang:

# The following will only perform a save on the database if enum.save_on_bang is set to true
user = User.new(role: :manager)
user.admin!

You can reach the I18n translations from three different ways, and the scopes are configured on enum.i18n_scopes. On the third one, only the scopes on enum.i18n_type_scope are used, that allows per-model customization.

user = User.new(role: :manager)
user.role.text                # User's manager
user.role_text                # User's manager
Enum::Roles.manager.text      # Manager
Clone repository
  • Arel
  • Auxiliary Statements
  • Belongs to Many
  • Box
  • Circle
  • Configuring
  • Date Time Range
  • Distinct On
  • Dynamic Attributes
  • Enum Set
  • Enum
  • Has Many
  • Home
  • Inherited Tables
  • Insert All
View All Pages

Menu

Explore Projects Groups Snippets