app/models/exhibit_finder.rb
# frozen_string_literal: true
##
# ExhibitFinder takes in a druid as the document_id and finds any published
# Exhibit that contains that document or is a document in the given collection
class ExhibitFinder
attr_reader :document_id
def initialize(document_id)
@document_id = document_id
end
def exhibits
@exhibits ||= Spotlight::Exhibit.includes(:thumbnail).where(slug: exhibit_slugs).published.discoverable
end
class << self
def find(document_id)
ExhibitFinder::JsonResponse.new(
new(document_id).exhibits
)
end
def search(query)
slugs = exhibit_slugs_for_search(query)
ExhibitFinder::JsonResponse.new(
Spotlight::Exhibit.includes(:thumbnail).where(slug: slugs).sort do |a, b|
slugs.index(a.slug) <=> slugs.index(b.slug) # sort the exhibits by the order of the slugs/results in solr
end
)
end
private
def exhibit_slugs_for_search(query)
query = "(#{query}) OR (#{query}*)"
documents = Blacklight.default_index.connection.select(
params: {
q: query,
qt: 'exhibit-titles',
rows: 10_000,
fl: 'exhibit_slug_ssi'
}
).dig('response', 'docs') || {}
documents.pluck('exhibit_slug_ssi')
end
end
private
def exhibit_slugs
documents.collect do |document|
document[exhibit_slug_field]&.select do |slug|
document[exhibit_public_field(slug)]&.all?
end
end.flatten.compact.uniq
end
def documents
@documents ||= solr_connection.select(
params: {
q: "(id:#{document_id} OR collection:#{document_id})",
fl: ['id', exhibit_slug_field, exhibit_public_field],
fq: '-document_type_ssi:exhibit',
facet: false,
rows: 10_000
}
).dig('response', 'docs') || []
end
def solr_connection
Blacklight.default_index.connection
end
def exhibit_public_field(slug = '*')
"exhibit_#{slug}_public_bsi"
end
def exhibit_slug_field
'spotlight_exhibit_slugs_ssim'
end
##
# Serialize the exhibits into JSON that includes additional attributes (e.g. thumbnail URL)
class JsonResponse
def initialize(exhibits)
@exhibits = exhibits
end
def as_json(*)
@exhibits.map do |exhibit|
thumbnail_url = exhibit&.thumbnail&.iiif_url
if thumbnail_url&.start_with?('/')
host = Settings.action_mailer.default_url_options.host
host = "https://#{host}" unless host.start_with?('http')
thumbnail_url = "#{host}#{thumbnail_url}"
end
exhibit.as_json.merge(
'thumbnail_url' => thumbnail_url
)
end
end
end
end