Module: ActiveEnum::Extensions::ClassMethods

Defined in:
lib/active_enum/extensions.rb

Instance Method Summary collapse

Instance Method Details

#active_enum_for(attribute) ⇒ Object



53
54
55
# File 'lib/active_enum/extensions.rb', line 53

def active_enum_for(attribute)
  enumerated_attributes && enumerated_attributes[attribute.to_sym]
end

#define_active_enum_methods_for_attribute(attribute) ⇒ Object



57
58
59
60
61
# File 'lib/active_enum/extensions.rb', line 57

def define_active_enum_methods_for_attribute(attribute)
  define_active_enum_read_method(attribute)
  define_active_enum_write_method(attribute)
  define_active_enum_question_method(attribute)
end

#define_active_enum_question_method(attribute) ⇒ Object

Define question method to check enum value against attribute value

Example:

user.sex?(:male)


127
128
129
130
131
132
133
134
135
136
137
# File 'lib/active_enum/extensions.rb', line 127

def define_active_enum_question_method(attribute)
  class_eval <<-DEF
    def #{attribute}?(*args)
      if args.first
        #{attribute} == self.class.active_enum_for(:#{attribute})[args.first]
      else
        super()
      end
    end
  DEF
end

#define_active_enum_read_method(attribute) ⇒ Object

Define read method to allow an argument for the enum component

Examples:

user.sex
user.sex(:id)
user.sex(:name)
user.sex(:enum)
user.sex(:meta_key)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/active_enum/extensions.rb', line 80

def define_active_enum_read_method(attribute)
  class_eval <<-DEF
    def #{attribute}(arg=nil)
      value = super()
      return if value.nil? && arg.nil?

      enum = self.class.active_enum_for(:#{attribute})
      case arg
      when :id
        value if enum[value]
      when :name
        enum[value]
      when :enum
        enum
      when Symbol
        (enum.meta(value) || {})[arg]
      else
        #{ActiveEnum.use_name_as_value ? 'enum[value]' : 'value' }
      end
    end
  DEF
end

#define_active_enum_write_method(attribute) ⇒ Object

Define write method to also handle enum value

Examples:

user.sex = 1
user.sex = :male


109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/active_enum/extensions.rb', line 109

def define_active_enum_write_method(attribute)
  class_eval <<-DEF
    def #{attribute}=(arg)
      if arg.is_a?(Symbol)
        value = self.class.active_enum_for(:#{attribute})[arg]
        super(value)
      else
        super(arg)
      end
    end
  DEF
end

#define_implicit_enum_class_for_attribute(attribute, block) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/active_enum/extensions.rb', line 63

def define_implicit_enum_class_for_attribute(attribute, block)
  enum_class_name = "#{name}::#{attribute.to_s.camelize}"
  eval("class #{enum_class_name} < ActiveEnum::Base; end")
  enum = enum_class_name.constantize
  enum.class_eval &block
  enum
end

#enumerate(*attributes, &block) ⇒ Object

Declare an attribute to be enumerated by an enum class

Example:

class Person < ActiveRecord::Base
  enumerate :sex, :with => Sex
  enumerate :sex # implies a Sex enum class exists

  # Pass a block to create implicit enum class namespaced by model e.g. Person::Sex
  enumerate :sex do
    value :id => 1, :name => 'Male'
  end

  # Multiple attributes with same enum
  enumerate :to, :from, :with => Sex


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/active_enum/extensions.rb', line 28

def enumerate(*attributes, &block)
  options = attributes.extract_options!
  self.enumerated_attributes ||= {}

  attributes_enum = {}
  attributes.each do |attribute|
    begin
      if block_given?
        enum = define_implicit_enum_class_for_attribute(attribute, block)
      else
        enum = options[:with] || attribute.to_s.camelize.constantize
      end

      attribute = attribute.to_sym
      attributes_enum[attribute] = enum

      define_active_enum_methods_for_attribute(attribute)
    rescue NameError => e
      raise e unless e.message =~ /uninitialized constant/
      raise ActiveEnum::EnumNotFound, "Enum class could not be found for attribute '#{attribute}' in class #{self}. Specify the enum class using the :with option."
    end
  end
  enumerated_attributes.merge!(attributes_enum)
end