Class: Compony::RequestContext

Inherits:
Dslblend::Base
  • Object
show all
Defined in:
lib/compony/request_context.rb

Overview

This encapsulates useful methods for accessing data within a request.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component, controller, *additional_providers, helpers: nil, locals: {}) ⇒ RequestContext

Returns a new instance of RequestContext.



10
11
12
13
14
15
16
17
18
# File 'lib/compony/request_context.rb', line 10

def initialize(component, controller, *additional_providers, helpers: nil, locals: {})
  # DSL provider is this class, controller is an additional provider, main provider should be the component
  # Note: we have to manually set the main provider here as the auto-detection sets it to the VerbDsl instance around the block,
  #       leading to undesired caching effects (e.g. components being re-used, even if the comp_opts have changed)
  @controller = controller
  @helpers = helpers || controller.helpers
  @local_assigns = locals.with_indifferent_access
  super(@helpers, @controller, *additional_providers, main_provider: component)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, **kwargs) ⇒ Object

Provide access to local assigns as if it were a Rails context



35
36
37
38
# File 'lib/compony/request_context.rb', line 35

def method_missing(method, *args, **kwargs, &)
  return @local_assigns[method] if @local_assigns.key?(method)
  return super
end

Instance Attribute Details

#controllerObject (readonly)

Allow explicit access to the controller object. All controller methods are delgated.



6
7
8
# File 'lib/compony/request_context.rb', line 6

def controller
  @controller
end

#helpersObject (readonly)



7
8
9
# File 'lib/compony/request_context.rb', line 7

def helpers
  @helpers
end

#local_assignsObject (readonly)



8
9
10
# File 'lib/compony/request_context.rb', line 8

def local_assigns
  @local_assigns
end

Instance Method Details

#componentObject



24
25
26
# File 'lib/compony/request_context.rb', line 24

def component
  @_main_provider
end

#content(name) ⇒ Object

Renders a content block from the current component.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/compony/request_context.rb', line 46

def content(name)
  name = name.to_sym
  content_block = component.content_blocks.find { |el| el.name == name }
  return false if content_block.nil?

  # We have to clear Rails' output_buffer to prevent double rendering of blocks. To achieve this, a fresh render context is instanciated.
  concat controller.render_to_string(
    type:   :dyny,
    locals: { render_component: component, render_controller: controller, render_locals: local_assigns, render_block: content_block },
    inline: <<~RUBY
      Compony::RequestContext.new(render_component, render_controller, helpers: self, locals: local_assigns).evaluate_with_backfire(&render_block.payload)
    RUBY
  )
  return true
end

#content!(name) ⇒ Object



62
63
64
# File 'lib/compony/request_context.rb', line 62

def content!(name)
  content(name) || fail("Content block #{name.inspect} not found in #{component.inspect}.")
end

#evaluate_with_backfireObject



20
21
22
# File 'lib/compony/request_context.rb', line 20

def evaluate_with_backfire(&)
  evaluate(backfire_vars: true, &)
end

#request_contextObject

Explicit accessor to this object. As Dslblend hides where a method comes from, this makes code modifying the request context more explicit. This is for instance useful when a component wishes to extend the request context with a module in order to define methods directly on the context.



30
31
32
# File 'lib/compony/request_context.rb', line 30

def request_context
  self
end

#respond_to_missing?(method, include_all) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
43
# File 'lib/compony/request_context.rb', line 40

def respond_to_missing?(method, include_all)
  return true if @local_assigns.key?(method)
  return super
end