Using Enums For Constant Data in Rails and ActiveRecord
I’ve been wondering what to write up for todays entry, in an effort to keep up the “post a day” discipline. I have about eight drafts sitting in the wordpress queue that are either incomplete thoughts or completely uninteresting posts. So I figured I’d take a look at what my next challenge is in my own project. After all, that’s what this site is for in some ways… a muse to get my off my butt and back into Rails code.
The last request that came in was for the ability to take a game object with a non-boolean, but discreet bit of data to specify if it is a boys only, girls only, or coed game. A constant you might say.
Back in the old perl world I’d probably look at doing something like adding an integer field to the database and then just remember that 1 = boys, 2 = girls and 0 = coed. Or something. Or was it 3 = coed? You see the problem here though. Having to remember the settings, and make sure that all the different files output the same values for the same settings… ugh. Even putting an output filter of some sort (or in rails parlance, a helper), is a bit of an ugly situation because that doesn’t help you with your database layer either. I might also have used the “Constant” or “ReadOnly”modules to do the same, or even gone with the more complex solution is to create a foreign key into another table called “gamegendertype” or something that just has the 1 = boys, 2 = girls, 3 = coded, but that’s unneeded complexity, database lookups/joins, etc (though it doesmake it easier to add another data type).
So I dug into it to find out what the canonical “rails way” was to do it. And that search led to enums. Enums allow you to specify your own discreet data types that can be searched on as if they were integers or the like, but are words like “Diamonds” “Hearts” “Clubs” and “Spades” for a solitaire game.
Rails doesn’t seem to have a built in way to do it, but the way that the various links I found had you do it were to store the string value in the backend database, but turn that into a :symbol for when it’s accessed to and from the front end. A link is worth a thousand words though
- Using constants in RoR, or how to use them with migrations, from StackOverflow
- Enumeration columns in rails
- An (older) Enum plugin
- ActiveRecord enums (#3 in the list, via the StackOverflow link)
For my project I’d rather not use a plugin (trying to learn by doing and all) so I’ll probably go with the virtual attribute method (last link). Keep an eye on the commit log on my github account to see where it goes