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';