Class: ViewComponentReflex::ReflexFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/view_component_reflex/reflex_factory.rb

Instance Method Summary collapse

Constructor Details

#initialize(component) ⇒ ReflexFactory

Returns a new instance of ReflexFactory.



3
4
5
6
7
# File 'lib/view_component_reflex/reflex_factory.rb', line 3

def initialize(component)
  @component = component
  @new = false
  reflex.component_class = component
end

Instance Method Details

#build_reflex_instanceObject

Beyond just creating the <Component>Reflex class, we need to define all the component methods on the reflex class. This replaces the old method_missing implementation, and passes more strict validation of recent SR versions



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
# File 'lib/view_component_reflex/reflex_factory.rb', line 41

def build_reflex_instance
  reflex_methods = @component.instance_methods - ViewComponentReflex::Component.instance_methods - [:call, :"_call_#{@component.name.underscore}"]
  component_allocate = @component.allocate
  Class.new(@component.reflex_base_class).tap do |klass|
    klass.instance_variable_set(:@__method_parameters, {})

    reflex_methods.each do |m|
      klass.instance_variable_get(:@__method_parameters)[m.to_s] = component_allocate.method(m).parameters
      klass.define_method(m) do |*args, &blk|
        delegate_call_to_reflex(m, *args, &blk)
      end
    end

    # SR does validation of incoming arguments against method definitions

    # so we need to fake our method definitions call here

    klass.define_method(:method) do |name|
      method = super(name)
      params = self.class.instance_variable_get(:@__method_parameters)

      if params && params[name]
        method.define_singleton_method(:parameters) do
          params[name]
        end
      end

      method
    end
  end
end

#nested?Boolean

Returns:

  • (Boolean)


9
10
11
# File 'lib/view_component_reflex/reflex_factory.rb', line 9

def nested?
  @nested ||= @component.name.include?("::")
end

#new?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/view_component_reflex/reflex_factory.rb', line 21

def new?
  @new
end

#reflexObject



25
26
27
28
29
30
31
# File 'lib/view_component_reflex/reflex_factory.rb', line 25

def reflex
  @reflex ||= if nested?
    reflex_from_nested_component
  else
    reflex_from_component
  end
end

#reflex_from_componentObject



86
87
88
89
90
91
92
93
# File 'lib/view_component_reflex/reflex_factory.rb', line 86

def reflex_from_component
  if Object.const_defined?(reflex_name)
    Object.const_get(reflex_name)
  else
    @new = true
    Object.const_set(reflex_name, reflex_instance)
  end
end

#reflex_from_nested_componentObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/view_component_reflex/reflex_factory.rb', line 71

def reflex_from_nested_component
  parent = if @component.respond_to? :module_parent
    @component.module_parent
  else
    @component.parent
  end

  if parent.const_defined?(reflex_name)
    parent.const_get(reflex_name)
  else
    @new = true
    parent.const_set(reflex_name, reflex_instance)
  end
end

#reflex_instanceObject



33
34
35
# File 'lib/view_component_reflex/reflex_factory.rb', line 33

def reflex_instance
  @reflex_instance ||= build_reflex_instance
end

#reflex_nameObject



13
14
15
16
17
18
19
# File 'lib/view_component_reflex/reflex_factory.rb', line 13

def reflex_name
  @reflex_name ||= if nested?
    @component.name.split("::").last
  else
    @component.name
  end + "Reflex"
end