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
On Gemcutter:
sudo gem install active_enum
And add to your Rails environment.rb
config.gem 'active_enum'
Example
Define an enum class with values
class Sex < ActiveEnum::Base
value :id => 1, :name => 'Male'
value :id => 2, :name => '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.
You can also define the sort order of returned values
class Sex < ActiveEnum::Base
order :desc
value :id => 1, :name => 'Male'
value :id => 2, :name => 'Female'
end
Enum class usage
Sex[1] # => 'Male'
Sex['Male'] # => 1
Sex[:male] # => 1
Sex.to_select # => [['Male', 1], ['Female',2]] for select form helpers
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 in enumerate block
class User < ActiveRecord::Base
# defines UserSex enum
enumerate :sex do
value :name => 'Male'
end
end
Multiple attributes with same enum
class Patient < ActiveRecord::Base
enumerate :to, :from, :with => Sex
end
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 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
A convience method on the class is available to the enum class of any enumerated attribute
User.enum_for(:sex) # => Sex
You can set the default to return the enum name value for enumerated attribute
ActiveEnum.use_name_as_value = true
user.sex # => 'Male'
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.
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
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?
-
possibly allow string enum values to assigned to attributes
-
add enum value class for instances if there is a need
Copyright © 2009 Adam Meehan, released under the MIT license