From b8ab01c46c119de64e45dc21e5a36e40ee99c8f8 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Wed, 27 May 2026 21:25:25 +0300 Subject: [PATCH] add dynamic documents to template response --- app/controllers/api/templates_controller.rb | 51 +++++++++++++++------ app/models/dynamic_document.rb | 6 +++ app/models/template.rb | 2 +- lib/templates/serialize_for_api.rb | 47 +++++++++++++------ 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/app/controllers/api/templates_controller.rb b/app/controllers/api/templates_controller.rb index 87b756ea..b3d05cec 100644 --- a/app/controllers/api/templates_controller.rb +++ b/app/controllers/api/templates_controller.rb @@ -9,20 +9,7 @@ module Api templates = paginate(templates.preload(:author, folder: :parent_folder)) - schema_documents = - ActiveStorage::Attachment.where(record_id: templates.map(&:id), - record_type: 'Template', - name: :documents, - uuid: templates.flat_map { |t| t.schema.pluck('attachment_uuid') }) - .preload(:blob) - - preview_image_attachments = - ActiveStorage::Attachment.joins(:blob) - .where(blob: { filename: ['0.png', '0.jpg'] }) - .where(record_id: schema_documents.map(&:id), - record_type: 'ActiveStorage::Attachment', - name: :preview_images) - .preload(:blob) + schema_documents, dynamic_documents, preview_image_attachments = preload_relations(templates) expires_at = Accounts.link_expires_at(current_account) @@ -30,6 +17,7 @@ module Api data: templates.map do |t| Templates::SerializeForApi.call(t, schema_documents: schema_documents.select { |e| e.record_id == t.id }, + dynamic_documents:, preview_image_attachments:, expires_at:) end, @@ -88,6 +76,41 @@ module Api private + def preload_relations(templates) + schema_documents = + ActiveStorage::Attachment.where(record_id: templates.map(&:id), + record_type: 'Template', + name: :documents, + uuid: templates.flat_map { |t| t.schema.pluck('attachment_uuid') }) + .preload(:blob) + + dynamic_document_uuids = + templates.flat_map { |t| t.schema.select { |item| item['dynamic'] }.pluck('attachment_uuid') } + + dynamic_documents = + if dynamic_document_uuids.present? + DynamicDocument.where(template: templates.map(&:id)) + .where(uuid: dynamic_document_uuids) + .preload(current_version: { document_attachment: :blob }) + .select(:id, :uuid, :template_id, :sha1, :created_at, :updated_at) + else + DynamicDocument.none + end + + preview_attachment_ids = + schema_documents.map(&:id) + dynamic_documents.filter_map { |d| d.current_version&.document_attachment&.id } + + preview_image_attachments = + ActiveStorage::Attachment.joins(:blob) + .where(blob: { filename: ['0.png', '0.jpg'] }) + .where(record_id: preview_attachment_ids, + record_type: 'ActiveStorage::Attachment', + name: :preview_images) + .preload(:blob) + + [schema_documents, dynamic_documents, preview_image_attachments] + end + def filter_templates(templates, params) templates = Templates.search(current_user, templates, params[:q]) templates = params[:archived].in?(['true', true]) ? templates.archived : templates.active diff --git a/app/models/dynamic_document.rb b/app/models/dynamic_document.rb index 8d93ff9a..354b0005 100644 --- a/app/models/dynamic_document.rb +++ b/app/models/dynamic_document.rb @@ -28,6 +28,12 @@ class DynamicDocument < ApplicationRecord has_many :versions, class_name: 'DynamicDocumentVersion', dependent: :destroy + has_one :current_version, class_name: 'DynamicDocumentVersion', + primary_key: %i[id sha1], + foreign_key: %i[dynamic_document_id sha1], + dependent: :destroy, + inverse_of: :dynamic_document + attribute :fields, :json before_validation :set_sha1 diff --git a/app/models/template.rb b/app/models/template.rb index 3679c946..ca8b8d0f 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -75,7 +75,7 @@ class Template < ApplicationRecord has_many :dynamic_document_versions, through: :dynamic_documents, source: :versions has_many :schema_dynamic_documents, lambda { |e| - where(uuid: e.schema.select { |e| e['dynamic'] }.pluck('attachment_uuid')) + where(uuid: e.schema.select { |item| item['dynamic'] }.pluck('attachment_uuid')) }, class_name: 'DynamicDocument', dependent: :destroy, inverse_of: :template scope :active, -> { where(archived_at: nil) } diff --git a/lib/templates/serialize_for_api.rb b/lib/templates/serialize_for_api.rb index ec9cb628..64907f50 100644 --- a/lib/templates/serialize_for_api.rb +++ b/lib/templates/serialize_for_api.rb @@ -14,27 +14,25 @@ module Templates module_function - def call(template, schema_documents: template.schema_documents.preload(:blob), preview_image_attachments: nil, - expires_at: Accounts.link_expires_at(Account.new(id: template.account_id))) + def call(template, schema_documents: template.schema_documents.preload(:blob), dynamic_documents: nil, + preview_image_attachments: nil, expires_at: Accounts.link_expires_at(Account.new(id: template.account_id))) json = template.as_json(SERIALIZE_PARAMS) - preview_image_attachments ||= - ActiveStorage::Attachment.joins(:blob) - .where(blob: { filename: ['0.jpg', '0.png'] }) - .where(record_id: schema_documents.map(&:id), - record_type: 'ActiveStorage::Attachment', - name: :preview_images) - .preload(:blob) + dynamic_documents ||= preload_dynamic_documents(template) - json['documents'] = template.schema.filter_map do |item| - attachment = schema_documents.find { |e| e.uuid == item['attachment_uuid'] } + preview_image_attachments ||= preload_preview_image_attachments(schema_documents, dynamic_documents) - unless attachment - Rollbar.error("Documents missing: #{template.id}") if defined?(Rollbar) + json['documents'] = template.schema.filter_map do |item| + if item['dynamic'] + dynamic_document = dynamic_documents.find { |e| e.uuid == item['attachment_uuid'] } - next + attachment = dynamic_document.current_version&.document_attachment end + attachment ||= schema_documents.find { |e| e.uuid == item['attachment_uuid'] } + + next unless attachment + first_page_blob = preview_image_attachments.find { |e| e.record_id == attachment.id }&.blob first_page_blob ||= attachment.preview_images.joins(:blob).find_by(blob: { filename: ['0.jpg', '0.png'] })&.blob @@ -49,5 +47,26 @@ module Templates json end + + def preload_dynamic_documents(template) + return DynamicDocument.none if template.schema.none? { |item| item['dynamic'] } + + template.schema_dynamic_documents + .preload(current_version: { document_attachment: :blob }) + .select(:id, :uuid, :template_id, :sha1, :created_at, :updated_at) + end + + def preload_preview_image_attachments(schema_documents, dynamic_documents) + record_ids = + schema_documents.map(&:id) + + dynamic_documents.filter_map { |d| d.current_version&.document_attachment&.id } + + ActiveStorage::Attachment.joins(:blob) + .where(blob: { filename: ['0.jpg', '0.png'] }) + .where(record_id: record_ids, + record_type: 'ActiveStorage::Attachment', + name: :preview_images) + .preload(:blob) + end end end