Class: SolidObjects::ComponentsController
- Inherits:
-
ActionController::Base
- Object
- ActionController::Base
- SolidObjects::ComponentsController
- Defined in:
- app/controllers/solid_objects/components_controller.rb,
sig/generated/controllers/solid_objects/components_controller.rbs
Constant Summary collapse
- BATCH_LIMIT =
50
Instance Method Summary collapse
- #batch ⇒ void
- #component_frame(registration, snapshot, rendered) ⇒ String
- #component_view_context ⇒ Object
- #newer_than_snapshot?(requested_revision, snapshot) ⇒ Boolean
- #refresh(payload) ⇒ void
- #refresh_batch(payload) ⇒ void
- #registration_payload(registration) ⇒ Hash[Symbol, untyped]
- #requested_revision_key ⇒ Array[Integer]
- #show ⇒ void
- #validate_single_batch!(registrations) ⇒ void
Instance Method Details
#batch ⇒ void
This method returns an undefined value.
17 18 19 |
# File 'app/controllers/solid_objects/components_controller.rb', line 17 def batch SolidObjects.instrument(:"component.batch_refreshed") { |payload| refresh_batch(payload) } end |
#component_frame(registration, snapshot, rendered) ⇒ String
179 180 181 182 |
# File 'app/controllers/solid_objects/components_controller.rb', line 179 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_context ⇒ Object
168 169 170 171 172 173 174 175 176 |
# File 'app/controllers/solid_objects/components_controller.rb', line 168 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
163 164 165 |
# File 'app/controllers/solid_objects/components_controller.rb', line 163 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.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'app/controllers/solid_objects/components_controller.rb', line 101 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 = SolidObjects .configuration . .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 |
#refresh_batch(payload) ⇒ void
This method returns an undefined value.
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 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'app/controllers/solid_objects/components_controller.rb', line 24 def refresh_batch(payload) tokens = Array(params.require(:tokens)) raise ActionController::ParameterMissing, :tokens if tokens.empty? raise ArgumentError if tokens.length > BATCH_LIMIT registrations = tokens.map { |token| ComponentRegistration.from_token(token) } validate_single_batch!(registrations) requested_revision = requested_revision_key snapshot = ActorSnapshot.new(registrations.first.reference) payload.merge!( actor_type: snapshot.reference.actor_type, actor_id: snapshot.reference.actor_id, batch: registrations.first.batch, components: registrations.map(&:component_name), instance_id: snapshot.instance_id, revision: snapshot.revision ) if newer_than_snapshot?(requested_revision, snapshot) payload[:outcome] = "conflict" return head :conflict end = SolidObjects .configuration . .call(controller: self) frames = registrations.map do |registration| rendered = ComponentRenderer.new( snapshot:, registration:, view_context: component_view_context, authorization_context: ).call { "target" => registration.dom_id, "revision" => "#{snapshot.instance_id}:#{snapshot.revision}", "refresh_method" => registration.refresh_method, "html" => component_frame(registration, snapshot, rendered) } end response.headers["Cache-Control"] = "private, no-store" payload[:outcome] = "rendered" render json: { "actor_type" => snapshot.reference.actor_type, "actor_id" => snapshot.reference.actor_id, "batch" => registrations.first.batch, "instance_id" => snapshot.instance_id, "revision" => snapshot.revision, "frames" => frames } 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]
142 143 144 145 146 147 148 149 150 151 |
# File 'app/controllers/solid_objects/components_controller.rb', line 142 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_key ⇒ Array[Integer]
154 155 156 157 158 159 160 |
# File 'app/controllers/solid_objects/components_controller.rb', line 154 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 |
#show ⇒ void
This method returns an undefined value.
12 13 14 |
# File 'app/controllers/solid_objects/components_controller.rb', line 12 def show SolidObjects.instrument(:"component.refreshed") { |payload| refresh(payload) } end |
#validate_single_batch!(registrations) ⇒ void
This method returns an undefined value.
88 89 90 91 92 93 94 95 96 97 98 |
# File 'app/controllers/solid_objects/components_controller.rb', line 88 def validate_single_batch!(registrations) first = registrations.first raise ArgumentError unless first.batch return if registrations.all? do |registration| registration.batch == first.batch && registration.reference.actor_type == first.reference.actor_type && registration.reference.actor_id == first.reference.actor_id end raise ArgumentError end |