Postgres имеет собственный тип перечисления , который во многих отношениях лучше, чем ограничение.
Перечислимые (перечисляемые) типы - это типы данных, которые включают stati c, упорядоченный набор значений. Они эквивалентны типам enum, поддерживаемым во многих языках программирования. Примером типа enum могут быть дни недели или набор значений состояния для фрагмента данных.
Это относится к популярной критике целочисленных столбцов ActiveRecord :: Enum, которые просто глядя из базы данных, вы не можете сказать, что на самом деле означают статусы. Это также не то же самое, что просто использование строкового столбца, поскольку значения сопоставляются с таблицей поиска и занимают только 4 байта на диске.
class AddStatusToProjects < ActiveRecord::Migration[5.2]
def up
execute <<-SQL
CREATE TYPE project_status AS ENUM ('pending', 'active', 'inactive');
SQL
add_column :project, :status, :project_status
end
def down
remove_column :projects, :status
execute <<-SQL
DROP TYPE project_status;
SQL
end
end
Затем настройте явное отображение для Enum в вашей модели:
class Project < ApplicationRecord
enum status: {
'pending' => :pending,
'active' => :active,
'inactive' => :inactive
}
# ...
end
Postgres обеспечит правильность значений для типа:
irb(main):022:0> Project.create!(status: 'foo')
(0.3ms) BEGIN
Project Create (3.6ms) INSERT INTO "projects" ("created_at", "updated_at", "status") VALUES ($1, $2, $3) RETURNING "id" [["created_at", "2020-01-16 14:15:47.579769"], ["updated_at", "2020-01-16 14:15:47.579769"], ["status", "foo"]]
(0.4ms) ROLLBACK
Traceback (most recent call last):
1: from (irb):22
ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: invalid input value for enum project_status: "foo")
Самое большое преимущество в том, что вам нужно использовать схему SQL вместо ruby Схема, поскольку она не может сбросить таблицу. Но это верно для многих Postgres функций.