module ActiveRecord::Enum
This is a work around to make ActiveRecord::Base#enum in Rails master works for Rails3
Declare an enum attribute where the values map to integers in the database, but can be queried by name. Example:
class Conversation < ActiveRecord::Base enum status: [ :active, :archived ] end Conversation::STATUS # => { active: 0, archived: 1 } # conversation.update! status: 0 conversation.active! conversation.active? # => true conversation.status # => :active # conversation.update! status: 1 conversation.archived! conversation.archived? # => true conversation.status # => :archived # conversation.update! status: 1 conversation.status = :archived
You can set the default value from the database declaration, like:
create_table :conversations do |t| t.column :status, :integer, default: 0 end
Good practice is to let the first declared status be the default.
Finally, it’s also possible to explicitly map the relation between attribute and database integer:
class Conversation < ActiveRecord::Base enum status: { active: 0, archived: 1 } end
Public Instance Methods
_enum_methods_module()
click to toggle source
# File lib/rails3_ac_enum/enum.rb, line 75 def _enum_methods_module @_enum_methods_module ||= begin mod = Module.new include mod mod end end
enum(definitions)
click to toggle source
# File lib/rails3_ac_enum/enum.rb, line 39 def enum(definitions) klass = self definitions.each do |name, values| enum_values = {} name = name.to_sym _enum_methods_module.module_eval do # def direction=(value) self[:direction] = DIRECTION[value] end define_method("#{name}=") { |value| value = value.to_s unless enum_values.has_key?(value) raise ArgumentError, "'#{value}' is not a valid #{name}" end self[name] = enum_values[value] } # def direction() DIRECTION.key self[:direction] end define_method(name) { enum_values.key self[name] } pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index pairs.each do |value, i| enum_values[value.to_s] = i # scope :incoming, -> { where direction: 0 } klass.scope value, -> { klass.where name => i } # def incoming?() direction == 0 end define_method("#{value}?") { self[name] == i } # def incoming! update! direction: :incoming end define_method("#{value}!") { update_attributes! name => value.to_sym } end end end end