Rails ActiveRecord::Enum Example

I’ve always had a fondness for the tidiness of enums so I was looking forward to having a reason to use ActiveRecord::Enum (official doc). What follows are my notes putting together an example Rails app to try to them out first. The source can be found on Github at jehughes/rails4-enum-example.

My environment for this is: Rails 4.2.1 / Ruby 2.1.6 / Ubuntu 14.04

Our sample application will be a list of projects with different status settings (the enum). I leave the amount of testing (or not) up to you. The source includes some basic rspec scripts. I’m also assuming familiarity with Rails; leave a comment if there’s a step I need to explain further.

Use an existing one or create a new Rails app:

(At this point I create a git repo, update to rspec, add bootstrap and various development/debugging gems. None of this is necessary for the example, just giving a heads up so it’s not a surprise when you see the source.)

Create a Project model with an enum attribute:

Edit the migration to update the status to a limit of 1 and default of 0:

NOTE: If you’ve set specific enum values, such as
enum: {this: 100, that: 215, the: 267, other: 345}
make sure the default matches a valid enum.

Don’t forget rake db:migrate

Using a console (pry, rails c, etc), try out the various methods available. They’re pretty self-explanatory and well documented.

One thing you’ll notice is a bias toward code where you already know the status. For example, Project.working! assumes you know the new status is :working. Before you start adding lines of if or case statements, I suggest a set_status method on the Project model that takes a string (another blog post):

And here’s an innocent looking item from the docs that should have dancing bells around it:

Use that class method when you need to know the ordinal value of an enum. For example, you can use that when manually building SQL strings:
Conversation.where(“status <> ?”, Conversation.statuses[:archived])

The moment I started refactoring an enum into a real world app, these two statements started showing up a lot:
Project.statuses[:working] which gives the ordinal value that’s actually stored in the database
and Project.statuses.keys which gives you an array of the enums names as strings.

Put the new enum into action:

Add a controller and views for Projects:

Or use the scaffold and tell it to ignore files that already exist.

With some editing, you should see your enum at work. I won’t repeat the contents of the controller and views here, you can see them in the source.

The controller is strictly standard stuff. Where the enum is displayed and selected in the views (show and form), you can see how straightforward it is to working with these enums.

One real world app item is the need to have alternate display names for the enum values rather than just using humanize or titleize. I used a locale file as you can see in this other blog post.

My conclusion… Still thinking about it. I can see using these in the future but not sure if it’s worth the effort to refactor my existing projects.