Postgres enums with Rails

Introduction

Enum - is a user-defined data type representing a set of named values. In general, the idea of enums aims to provide 2 main purposes:

to make codebase more readable and human-friendly

to add extra type safety by limiting possible assignable value to the variable of enum type

Enum is based on integer type data type, what is definitely good for performance. If we are going to deal with a lot of data.

The "Old school" way

The most common way of using "enum" is the definite state of some object. In spite of having no enums in pure Ruby, we are able to emulate them with constants or symbols. Here is the sample of old-styled Rails 3 (legacy) data-model source code:

classAccount<ActiveRecord::BasePAID_STATUS='paid'OVERDUE_STATUS='ovedue'BLOCKED_STATUS='blocked'STATUSES=[PAID_STATUS,OVERDUE_STATUS,BLOCKED_STATUS].freezevalidates:status,presence: true,inclusion: {in: STATUSES}defpaid?self.status==PAID_STATUSendend# everywhere we work with Account instance - it is much easier# to deal with helper predicate instead of comparing values "in place"ifaccount.paid?# do something special for the user who paysend

It gives more readability to the codebase and makes it looks friendly for a new developer! But it is overloaded with boilerplates - constants definition and values checking. This checks spread all over the codebase and make maintenance more difficult.

Conclusion

Postgres enums are great and helpful!
They are very easy to integrate with Rails!
They help to ensure data consistency for the definite set of values. The increase human-readability of the data out of the Rails application context.
They also have better performance (comparing to text values).