has_enumeration
Overview
has_enumeration adds support for enumerated types to ActiveRecord. The values
of an enumerated attribute are represented as symbols regardless of the
attribute's underlying representation in the database. Predicates
(e.g. car.color.red?) are provided for each value of the enumerated type.
Defining Enumerated Attributes
Enumerated attributes are declared in the model's class definition with the
has_enumeration class method. For example:
class Car < ActiveRecord::Base
has_enumeration :color, [:red, :green, :blue]
end
The above definition assumes that the color attribute is stored as a string
and that its values in the database match those obtained by calling to_s on
their corresponding symbols. I.e., :red is stored as 'red'.
If the underlying column is not a string or its values do not match the string version of the enumeration's symbols, then the mapping between symbols and their underlying values may be provided as a hash:
class Car < ActiveRecord::Base
has_enumeration :color, :red => 1, :green => 2, :blue => 3
end
By default, the underlying attribute is assumed to have the same name as the
enumeration. If this is not the case, the name of the underlying attibute may
be provided with the :attribute option:
class Car < ActiveRecord::Base
has_enumeration :color, {:red => 1, :green => 2, :blue => 3},
:attribute => :hue
end
Using Enumerated Attributes
Assignment
Enumerated attributes are assigned using symbols:
car = Car.new(:color => :red)
car.color = :blue
The symbols are coerced into an instance of a nested class (Car::Color in
this example) that is created by has_enumeration. If for some reason you
need to avoid the type coercion, you can assign a value of that class directly:
car.color = Car::Color.from_sym(:green)
Querying
When constructing queries referencing the enumerated attribute, use the symbol as its value:
Car.find(:all, :conditions => {:color => :red})
has_enumeration supports Rails 3 and is aware of the model's underlying Arel
representation:
Car.where(:color => :red)
Car.where(Car.arel_table[:color].not_in([:red, :green]))
If you are using MetaWhere, has_enumeration plays nicely with it:
# This example requires the meta_where:
Car.where(:color.not_in => [:red, :green])
Testing Values
The primary means of interacting with enumerated attributes is through the predicate methods that are automatically generated for each value in the enumeration:
car = Car.new(:color => :red)
car.color.red?
# => true
car.color.green?
# => false
If the value of the attribute is needed as a symbol, e.g., for direct
comparison, it can be retrieved with to_sym:
car.color.to_sym
# => :red
Installation
has_enumeration is packaged as a gem:
gem install has_enumeration
Rails 3
To use has_enumeration with Rails 3, simply add it to your application's
Gemfile:
gem 'has_enumeration'
Rails 2.x
To use has_enumeration with Rails 2, add it to your application's
environment.rb file:
config.gem 'has_enumeration'
Supported Configurations
has_enumeration has been tested with the following versions of ActiveRecord:
- 2.3.10
- 3.0.1
- 3.0.3
and the following Ruby implementations:
- 1.8.7-p302
- 1.9.2-p0
- JRuby 1.5.5
- Rubinius 1.1.0
Getting the Latest
has_enumeration is hosted on github at
http://github.com/gregspurrier/has_enumeration.
You can make a local clone of the repository with the following command:
git clone git://github.com/gregspurrier/has_enumeration.git
License
has_enumeration is Copyright 2010 by Greg Spurrier. It is released under
the MIT License. Please see LICENSE.txt for details.