Module: ActiveRecord::StringEnum
- Defined in:
- lib/active_record/string_enum.rb,
lib/active_record/string_enum/version.rb
Overview
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.update! status: :active
conversation.active!
conversation.active? # => true
conversation.status # => "active"
# conversation.update! status: :archived
conversation.archived!
conversation.archived? # => true
conversation.status # => "archived"
# conversation.update! status: :archived
conversation.status = "archived"
# conversation.update! status: nil
conversation.status = nil
conversation.status.nil? # => true
conversation.status # => nil
Scopes based on the allowed values of the enum field will be provided as well. With the above example:
Conversation.active
Conversation.archived
Of course, you can also query them directly if the scopes doesn’t fit your needs:
Conversation.where(status: [:active, :archived])
Conversation.where.not(status: :active)
You can set the default value from the database declaration, like:
create_table :conversations do |t|
t.column :status, :string, default: :active
end
In rare circumstances you might need to access the mapping directly. The mappings are exposed through a class method with the pluralized attribute name.
Conversation.statuses[0] # => :active
Conversation.statuses[1] # => :archived
Defined Under Namespace
Classes: EnumType
Constant Summary collapse
- VERSION =
"0.0.2"
Class Method Summary collapse
-
.extended(base) ⇒ Object
:nodoc:.
Instance Method Summary collapse
Class Method Details
.extended(base) ⇒ Object
:nodoc:
58 59 60 61 |
# File 'lib/active_record/string_enum.rb', line 58 def self.extended(base) # :nodoc: base.class_attribute(:defined_str_enums) base.defined_str_enums = {} end |
Instance Method Details
#inherited(base) ⇒ Object
:nodoc:
63 64 65 66 |
# File 'lib/active_record/string_enum.rb', line 63 def inherited(base) # :nodoc: base.defined_str_enums = defined_str_enums.deep_dup super end |
#str_enum(definitions) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/active_record/string_enum.rb', line 98 def str_enum(definitions) klass = self definitions.each do |name, values| # statuses = [ ] enum_values = values.map(&:to_s) name = name.to_sym # def self.statuses statuses end detect_enum_conflict!(name, name.to_s.pluralize, true) klass.singleton_class.send(:define_method, name.to_s.pluralize) { values } detect_enum_conflict!(name, name) detect_enum_conflict!(name, "#{name}=") # TODO: in Rails 4.2.1 this will be legal: # attribute name, EnumType.new(name, enum_values) # instead of the next lines: type = EnumType.new(name, enum_values) define_method("#{name}=") do |value| write_attribute(name, type.cast(value)) end define_method(name) { type.deserialize(self[name]) } _enum_methods_module.module_eval do enum_values.each do |value| # def active?() status == :active end klass.send(:detect_enum_conflict!, name, "#{value}?") define_method("#{value}?") { self[name] == value } # def active!() update! status: :active end klass.send(:detect_enum_conflict!, name, "#{value}!") define_method("#{value}!") { update! name => value } # scope :active, -> { where status: :active } klass.send(:detect_enum_conflict!, name, value, true) klass.scope value, -> { klass.where name => value } end end defined_str_enums[name.to_s] = enum_values end end |