= ActiveEnum Define enum classes in Rails and use them to enumerate ActiveRecord attributes. Brings together some ideas of similar plugins that I liked and does it they way I prefer. Enum values are stored in memory at the moment but I plan to add database and yaml. == Install For Rails 2.x only gem install active_enum --version '~> 0.6.0' And add to your Rails environment.rb config.gem 'active_enum', :version => '~> 0.6.0' == Example Define an enum class with values class Sex < ActiveEnum::Base value :id => 1, :name => 'Male' value :id => 2, :name => 'Female' end Define with id as the key class Sex < ActiveEnum::Base value 1 => 'Male' value 2 => 'Female' end Define using implicit id values class Sex < ActiveEnum::Base value :name => 'Male' value :name => 'Female' end Beware that if you change the order of values defined in an enum which don't have explicit ids, then the ids will change. This could corrupt your data if the enum values have been stored in a model record, as they will no longer map to the original enum. Enum class usage Sex[1] # => 'Male' Sex['Male'] # => 1 Sex[:male] # => 1 Sex.to_select # => [['Male', 1], ['Female',2]] for select form helpers === Ordering To define the sorting of returned values use the order method. Which is useful for to_select method. class Sex < ActiveEnum::Base order :asc value :id => 1, :name => 'Male' value :id => 2, :name => 'Female' end By default the order is ascending (:asc) but you can also choose descending (:desc) or in order of definition (:as_defined). The last option is useful when supplying id values but have a specific order needed to display them. === Enumerate model attributes Use the enum to enumerate an ActiveRecord model attribute class User < ActiveRecord::Base enumerate :sex, :with => Sex end Skip the with option if the enum can be implied from the attribute class User < ActiveRecord::Base enumerate :sex end Define enum class implicitly from enumerate block. Enum class is namespaced by model class. class User < ActiveRecord::Base # defines User::Sex enum class enumerate :sex do value :name => 'Male' end end Multiple attributes with same enum class Patient < ActiveRecord::Base enumerate :to, :from, :with => Sex end === Attribute value lookup Access the enum values and the enum class using the attribute method with a symbol for the enum component you want user = User.new user.sex = 1 user.sex # => 1 user.sex(:id) # => 1 user.sex(:name) # => 'Male' user.sex(:enum) # => Sex You can set the default to return the enum name value for enumerated attribute ActiveEnum.use_name_as_value = true user.sex # => 'Male' === Boolean check You can check if the attribute value matches a particular enum value by passing the enum value as an argument to the question method user.sex?(:male) # => true user.sex?(:Male) # => true user.sex?('Male') # => true user.sex?('Female') # => false === Enum lookup A convenience method on the class is available to the enum class of any enumerated attribute User.active_enum_for(:sex) # => Sex === Bulk definition Define enum classes in bulk without class files, in an initializer file for example. ActiveEnum.define do # defines Sex enum(:sex) do value :name => 'Male' value :name => 'Female' end # defines Language enum(:language) do value :name => 'English' value :name => 'German' end end All defined enum classes are stored in ActiveEnum.enum_classes array if you need look them up or iterate over them. === Model as enum or acts_as_enum You can make an existing model class behave like an enum class with acts_as_enum class User < ActiveRecord::Base acts_as_enum :name_column => 'first_name' end Giving you the familiar enum methods User[1] User['Dave'] User.to_select === Formtastic If you are a formtastic user you can use the extension for an enum input. In an initialiser: require 'active_enum/formtastic' Then in a form you can use the :enum type for attribute inputs which are enumerated. <% semantic_form_for(@person) do |f| %> <%= f.input :sex, :as => :enum %> <% end %> This will output a select with the option values taken from the enum class for the attribute. == TODO * more docs * storage options of memory, database or yaml * use custom method name for the enumerated attribute * named_scopes * question methods for enum names e.g. user.male? Copyright (c) 2009 Adam Meehan, released under the MIT license