module EnumX::DSL
Mixin for any ActiveRecord or ActiveModel object to support enums.
Usage¶ ↑
First, make sure your model class includes EnumX::DSL
:
include EnumX::DSL
Then, define any enum-like attribute using the {#enum} method. The best enum is always inferred. The following are identical:
enum :status, :statuses enum :status, EnumX.statuses enum :status, EnumX[:statuses] enum :status
The latter infers the 'statuses' enum by default. If no applicable enum was found, an error is thrown.
Multi-enums¶ ↑
Specify the option +:flags => true+ to allow the attribute to contain multiple enum values at once. The attribute will in essence become an array.
@see ClassMethods#enum
Public Class Methods
define_mnemonics(target, attribute, enum)
click to toggle source
Mnemonics (single & multi)
# File lib/enum_x/dsl.rb, line 349 def self.define_mnemonics(target, attribute, enum) enum.values.each do |value| target.class_eval <<-RUBY, __FILE__, __LINE__+1 def #{value}? :#{value} === #{attribute} end RUBY end end
define_multi_reader(target, attribute)
click to toggle source
Multi enum reader & writer
# File lib/enum_x/dsl.rb, line 321 def self.define_multi_reader(target, attribute) define_reader target, attribute, <<-RUBY enum = EnumX.find(self.class, :#{attribute.to_s}) case value = %{read_value} when nil then nil when EnumX::ValueList then value when Enumerable then EnumX::ValueList.new(enum, value) else EnumX::ValueList.new(enum, [value]) end RUBY end
define_multi_writer(target, attribute)
click to toggle source
# File lib/enum_x/dsl.rb, line 333 def self.define_multi_writer(target, attribute) define_writer target, attribute, <<-RUBY enum = EnumX.find(self.class, :#{attribute.to_s}) value = case value when nil then nil when EnumX::ValueList then value when Enumerable then EnumX::ValueList.new(enum, value) else EnumX::ValueList.new(enum, [value]) end %{write_value} RUBY end
define_reader(target, attribute, body)
click to toggle source
Defines a generic attribute reader ActiveModel-like classes. @api private
# File lib/enum_x/dsl.rb, line 225 def self.define_reader(target, attribute, body) override = target.instance_methods.include?(attribute.to_sym) value_reader = case true when override "#{attribute}_without_enums" when target.instance_methods.include?(:read_attribute) || target.private_instance_methods.include?(:read_attribute) "read_attribute(:#{attribute})" else # We need a reader to fall back to. raise "cannot overwrite enum reader - no existing reader found" end body.gsub! '%{read_value}', value_reader if override target.class_eval <<-RUBY, __FILE__, __LINE__+1 def #{attribute}_with_enums #{body} end alias_method_chain :#{attribute}, :enums RUBY else target.class_eval <<-RUBY, __FILE__, __LINE__+1 def #{attribute} #{body} end RUBY end end
define_single_reader(target, attribute)
click to toggle source
Single enum reader & writer
# File lib/enum_x/dsl.rb, line 293 def self.define_single_reader(target, attribute) define_reader target, attribute, <<-RUBY case value = %{read_value} when EnumX::Value then value when nil then nil else enum = EnumX.find(self.class, :#{attribute.to_s.pluralize}) enum[value] || value end RUBY end
define_single_writer(target, attribute)
click to toggle source
# File lib/enum_x/dsl.rb, line 305 def self.define_single_writer(target, attribute) define_writer target, attribute, <<-RUBY value = case value when EnumX::Value then value when nil then nil else enum = EnumX.find(self.class, :#{attribute.to_s.pluralize}) enum[value] || value end %{write_value} RUBY end
define_writer(target, attribute, body)
click to toggle source
Defines a generic attribute writer ActiveModel-like classes. @api private
# File lib/enum_x/dsl.rb, line 258 def self.define_writer(target, attribute, body) method = :"#{attribute}=" override = target.instance_methods.include?(method) value_writer = case true when override "self.#{attribute}_without_enums = value" when target.instance_methods.include?(:write_attribute) || target.private_instance_methods.include?(:write_attribute) "write_attribute :#{attribute}, value" else # We need a writer to fall back to. raise "cannot overwrite enum writer - no existing writer found" end body.gsub! '%{write_value}', value_writer if override target.class_eval <<-RUBY, __FILE__, __LINE__+1 def #{attribute}_with_enums=(value) #{body} end alias_method_chain :#{attribute}=, :enums RUBY else target.class_eval <<-RUBY, __FILE__, __LINE__+1 def #{attribute}=(value) #{body} end RUBY end end
included(target)
click to toggle source
# File lib/enum_x/dsl.rb, line 30 def self.included(target) target.extend ClassMethods end