Module: EnumFor

Defined in:
lib/enum_for.rb,
lib/enum_for/version.rb

Overview

Public: Module that extends class in order to define enum methods using enum_for class method.

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
'0.1.0'.freeze

Instance Method Summary collapse

Instance Method Details

#enum_for(hash) ⇒ NilClass

Public: Defines few methods useful for handling integer attributes which have to be used by enums. There is ActiveRecord enum type, but it shouldn’t be exposed in API as it doesn’t handle validations well (it raises exception when wrong enum is sent, while we would like to validate enum)

This method doesn’t prevent enum names to be reserved ruby words so please use with caution.

Methods generated by enum_for defined as:

enum_for color: { red: 0, green: 1 }

When enum is set to 1:

object.color

> ‘green’

object.red?

> false

object.green?

> true

object.class.colors

> { red: 0, green: 1 }

object.color_to_enum

> 1

It also adds validation:

validates :color, presence: true, inclusion: colors.keys

Returns:

  • (NilClass)


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/enum_for.rb', line 47

def enum_for(hash)
  enum_name = hash.keys.first.to_s
  mapping   = hash.values.first.with_indifferent_access

  define_singleton_method(enum_name.pluralize) do
    mapping
  end

  define_method(enum_name) do
    return nil if self[enum_name].blank?

    mapping.key(self[enum_name]).to_s
  end

  define_method("#{enum_name}=") do |value|
    begin
      self[enum_name] = Integer(value)
    rescue ArgumentError, TypeError
      self[enum_name] = mapping[value.to_s.downcase]
    end
  end

  mapping.each do |name, _|
    define_method "#{name}?" do
      public_send(enum_name).to_s == name
    end
  end

  mapping.each do |name, value|
    define_method "#{name}!" do
      public_send("#{enum_name}=", value)
      save!
    end
  end

  define_method("#{enum_name}_to_enum") do
    self[enum_name]
  end

  nil
end