Postgres 有一个native enum type,它实际上在很多方面都比一个约束要好。
枚举(enum)类型是包含静态、有序的数据类型
一组值。它们等价于 a 中支持的枚举类型
编程语言的数量。枚举类型的一个示例可能是
星期几,或一组数据的状态值。
这解决了对 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 的许多功能来说都是如此。