A lesser known fact about PG enums is that they are ordered. This can be really handy when values have an implicit ordering.
Let's imagine a record Issue(criticality: string)
. criticality
should have the following three possible values: critical
, medium
, low
.
Sorting with Issue.all.order(criticality: :desc)
will return the following order:
- The
'medium'
issue - The
'low'
issue - The
'critical'
issue
This happens because the database column backing the criticality attribute is a string and PG will use a collation Show archive.org snapshot to determine the result of comparisons. In most collations, the following SQL statements explain the sorting above:
SELECT 'medium' > 'low'; // true
SELECT 'medium' > 'critical'; // true
SELECT 'low' > 'medium'; // false
SELECT 'low' > 'critical'; // true
SELECT 'critical' > 'low'; // false
SELECT 'critical' > 'medium'; // false
Using an enum
Let's change the type of the Issue
to an actual enum with the following definition:
CREATE TYPE criticality AS ENUM ('low', 'medium', 'critical');
Sorting with Issue.all.order(criticality: :desc)
will now return the following order:
- The
'critical'
issue - The
'medium'
issue - The
'low'
isse
PG Enums are ordered
Show archive.org snapshot
based on their specified order when creating them, in this case ('low', 'medium', 'critical')
.
When adding a new value, you can choose its position:
ALTER TYPE criticality ADD VALUE 'high' AFTER 'medium';