Written by Rob Morris @ Irongaze Consulting LLC (irongaze.com)
Add support for rich enum values (enumerated constants) to Ruby/Rails.
Managing constants - status flags, system states, etc - is frustrating when working with Ruby and Rails. The canonical solution is to use class constants. But doing so leaves a lot to be desired. This gem provides a much more Ruby-like way of dealing with magic constants that provides symbol/key-based lookup, automatic conversion between keys and values, user-friendly naming, attribute support, model scoping and validation, and more.
To use:
# Require the gem's classes (not needed if using Bundler) require 'iron/enum' # Declare an enum module. In this case, let's say we're working on a # shopping cart system that tracks orders. Orders have a status - perfect # place for an enumeration! module OrderStatus enum :created, 1 enum :cancelled, 2, 'No Sale' enum :purchased, 3 enum :shipped, 4 enum :returned, 5 end # Once you have your enum set up, there are a host of things you can do. # To start with, enums set up normal Ruby class constants: >> puts OrderStatus::PURCHASED => 3 # But you can also refer to them with symbolic keys: >> puts OrderStatus.value(:purchased) => 3 # You can convert between values, keys and text: >> OrderStatus.value(:shipped) => 4 >> OrderStatus.name(:shipped) => 'Shipped' >> OrderStatus.key(4) => :shipped # Validate values against the set of good values >> OrderStatus.valid_value?(10) => false # Get an array of all valid values >> OrderStatus.values => [1, 2, 3, 4, 5] # Get a selection of values by key >> OrderStatus.values(:created, :cancelled, :returned) => [1, 2, 5] # This is all handy, but where enums really shine is as declared attributes class Order < ActiveRecord::Base # Pass the attribute and the enum module that it uses enum_attr :status => OrderStatus # Note that if your attribute's name maps to your enum module name, you can skip the hash: # enum_attr :order_status end # Now you can set a value using a key >> @order = Order.new >> @order.status = :shipped => 4 # Test for a given value with a clear syntax >> @order.status_returned? => false # Set a value >> @order.status_returned! => 5 # Setting an invalid value raises an exception # This raises RuntimeError('Unknown key or value [27] in enum OrderStatus') >> @order.status = 27 # You even get free scoping! >> Order.with_status(:shipped) => [...all orders with status == 4...] # And model validation, should you somehow set the field to an improper value >> @order = Order.new >> @order.send(:write_attribute, :status, -2) >> @order.valid? => false
None, though you’ll need rspec, sqlite3 and active_record gems to test and build the gem
To install, simply run:
sudo gem install iron-enum
RVM users can skip the sudo:
gem install iron-enum
Once installed, just require it:
require 'iron-enum'