Class: SolidObjects::ComponentsController

Inherits:
ActionController::Base show all
Defined in:
app/controllers/solid_objects/components_controller.rb,
sig/generated/controllers/solid_objects/components_controller.rbs

Instance Method Summary collapse

Instance Method Details

#component_frame(registration, snapshot, rendered) ⇒ String

RBS:

  • (ComponentRegistration, ActorSnapshot, untyped) -> String

Parameters:

Returns:

  • (String)


95
96
97
98
# File 'app/controllers/solid_objects/components_controller.rb', line 95

def component_frame(registration, snapshot, rendered)
  revision = "#{snapshot.instance_id}:#{snapshot.revision}"
  %(<turbo-frame id="#{registration.dom_id}" data-solid-objects-revision="#{revision}" data-solid-objects-refresh="#{registration.refresh_method}">#{rendered}</turbo-frame>).html_safe
end

#component_view_contextObject

RBS:

  • () -> untyped

Returns:

  • (Object)


84
85
86
87
88
89
90
91
92
# File 'app/controllers/solid_objects/components_controller.rb', line 84

def component_view_context
  if defined?(Rails) && Rails.application
    prepend_view_path(*Rails.application.paths["app/views"].existent)
  end

  view_context.tap do |context|
    context.extend(Rails.application.helpers) if defined?(Rails) && Rails.application
  end
end

#newer_than_snapshot?(requested_revision, snapshot) ⇒ Boolean

RBS:

  • (Array[Integer], ActorSnapshot) -> bool

Parameters:

Returns:

  • (Boolean)


79
80
81
# File 'app/controllers/solid_objects/components_controller.rb', line 79

def newer_than_snapshot?(requested_revision, snapshot)
  (requested_revision <=> [ snapshot.instance_id, snapshot.revision ]) == 1
end

#refresh(payload) ⇒ void

This method returns an undefined value.

RBS:

  • (Hash[Symbol, untyped]) -> void

Parameters:

  • (Hash[Symbol, untyped])


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
# File 'app/controllers/solid_objects/components_controller.rb', line 17

def refresh(payload)
  registration = ComponentRegistration.from_token(
    params.require(:token)
  )
  payload.merge!(registration_payload(registration))
  requested_revision = requested_revision_key
  snapshot = ActorSnapshot.new(registration.reference)
  payload[:instance_id] = snapshot.instance_id
  payload[:revision] = snapshot.revision
  if newer_than_snapshot?(requested_revision, snapshot)
    payload[:outcome] = "conflict"
    return head :conflict
  end

  authorization_context = SolidObjects
    .configuration
    .component_authorization_context
    .call(controller: self)
  rendered = ComponentRenderer.new(
    snapshot:,
    registration:,
    view_context: component_view_context,
    authorization_context:
  ).call
  response.headers["Cache-Control"] = "private, no-store"
  payload[:outcome] = "rendered"
  render html: component_frame(registration, snapshot, rendered)
rescue Unauthorized
  payload[:outcome] = "unauthorized"
  head :forbidden
rescue UnknownComponent
  payload[:outcome] = "unknown_component"
  head :not_found
rescue ActionController::ParameterMissing,
  ArgumentError,
  InvalidComponentToken
  payload[:outcome] = "invalid_token"
  head :bad_request
end

#registration_payload(registration) ⇒ Hash[Symbol, untyped]

RBS:

  • (ComponentRegistration) -> Hash[Symbol, untyped]

Parameters:

Returns:

  • (Hash[Symbol, untyped])


58
59
60
61
62
63
64
65
66
67
# File 'app/controllers/solid_objects/components_controller.rb', line 58

def registration_payload(registration)
  {
    actor_type: registration.reference.actor_type,
    actor_id: registration.reference.actor_id,
    component_name: registration.component_name,
    component_key: registration.component_key,
    dependencies: registration.dependencies,
    refresh_method: registration.refresh_method
  }
end

#requested_revision_keyArray[Integer]

RBS:

  • () -> Array[Integer]

Returns:

  • (Array[Integer])


70
71
72
73
74
75
76
# File 'app/controllers/solid_objects/components_controller.rb', line 70

def requested_revision_key
  instance_id = Integer(params.fetch(:instance_id), 10)
  revision = Integer(params.fetch(:revision), 10)
  raise ArgumentError if instance_id.negative? || revision.negative?

  [ instance_id, revision ]
end

#showvoid

This method returns an undefined value.

RBS:

  • () -> void



10
11
12
# File 'app/controllers/solid_objects/components_controller.rb', line 10

def show
  SolidObjects.instrument(:"component.refreshed") { |payload| refresh(payload) }
end