Module: EnumMachine::BuildValueClass

Defined in:
lib/enum_machine/build_value_class.rb

Class Method Summary collapse

Class Method Details

.call(enum_values:, i18n_scope:, value_decorator:, machine: nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
# File 'lib/enum_machine/build_value_class.rb', line 5

def self.call(enum_values:, i18n_scope:, value_decorator:, machine: nil)
  aliases = machine&.instance_variable_get(:@aliases) || {}

  Class.new(String) do
    include(value_decorator) if value_decorator

    define_method(:machine) { machine }
    define_method(:enum_values) { enum_values }
    private :enum_values, :machine

    def inspect
      "#<EnumMachine \"#{self}\">"
    end

    if machine&.transitions?
      def possible_transitions
        machine.possible_transitions(self)
      end

      def can?(enum_value)
        possible_transitions.include?(enum_value)
      end
    end

    enum_values.each do |enum_value|
      enum_name = enum_value.underscore

      define_method(:"#{enum_name}?") do
        self == enum_value
      end

      if machine&.transitions?
        define_method(:"can_#{enum_name}?") do
          possible_transitions.include?(enum_value)
        end
      end
    end

    aliases.each_key do |key|
      define_method(:"#{key}?") do
        machine.fetch_alias(key).include?(self)
      end
    end

    if i18n_scope
      full_scope = "enums.#{i18n_scope}"
      define_method(:human_name) do
        ::I18n.t(self, scope: full_scope, default: self)
      end
    end

    def respond_to_missing?(method_name, _include_private = false)
      method_name = method_name.name if method_name.is_a?(Symbol)

      method_name.end_with?("?") &&
        method_name.include?("__") &&
        (method_name.delete_suffix("?").split("__") - enum_values).empty?
    end

    def method_missing(method_name)
      return super unless respond_to_missing?(method_name)

      m_enums = method_name.name.delete_suffix("?").split("__")
      self.class.define_method(method_name) { m_enums.include?(self) }
      send(method_name)
    end
  end
end