Class: Wings::Valkyrie::QueryService

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/wings/valkyrie/query_service.rb

Overview

Note:

does not support duplicates!

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter:) ⇒ QueryService

Returns a new instance of QueryService.

Parameters:


15
16
17
# File 'lib/wings/valkyrie/query_service.rb', line 15

def initialize(adapter:)
  @adapter = adapter
end

Instance Attribute Details

#adapterObject (readonly)

Returns the value of attribute adapter


8
9
10
# File 'lib/wings/valkyrie/query_service.rb', line 8

def adapter
  @adapter
end

Instance Method Details

#count_all_of_model(model:) ⇒ Integer

Parameters:

  • :model (Class)

Returns:

  • (Integer)

23
24
25
26
27
28
# File 'lib/wings/valkyrie/query_service.rb', line 23

def count_all_of_model(model:)
  ActiveFedora::Base
    .where(has_model_ssim: [model_class_for(model).to_rdf_representation,
                            model.new.internal_resource.to_s])
    .count
end

#custom_queriesValkyrie::Persistence::CustomQueryContainer

Constructs a Valkyrie::Persistence::CustomQueryContainer using this query service

Returns:

  • (Valkyrie::Persistence::CustomQueryContainer)

198
199
200
# File 'lib/wings/valkyrie/query_service.rb', line 198

def custom_queries
  @custom_queries ||= ::Valkyrie::Persistence::CustomQueryContainer.new(query_service: self)
end

#find_allArray<Valkyrie::Resource>

Find all work/collection records, and map to Valkyrie Resources

Returns:

  • (Array<Valkyrie::Resource>)

54
55
56
57
58
# File 'lib/wings/valkyrie/query_service.rb', line 54

def find_all
  ::ActiveFedora::Base.all.map do |obj|
    resource_factory.to_resource(object: obj)
  end
end

#find_all_of_model(model:) ⇒ Array<Valkyrie::Resource>

Find all work/collection records of a given model, and map to Valkyrie Resources

Parameters:

  • model (Class)

Returns:

  • (Array<Valkyrie::Resource>)

66
67
68
69
70
# File 'lib/wings/valkyrie/query_service.rb', line 66

def find_all_of_model(model:)
  model_class_for(model).all.map do |obj|
    resource_factory.to_resource(object: obj)
  end
end

#find_by(id:) ⇒ Valkyrie::Resource

WARNING: In general, prefer find_by_alternate_identifier over this method.

Hyrax uses a shortened noid in place of an id, and this is what is stored in ActiveFedora, which is still the storage backend for Hyrax.

If you do not heed this warning, then switch to Valyrie's Postgres MetadataAdapter, but continue passing noids to find_by, you will start getting ObjectNotFoundErrors instead of the objects you wanted

Find a record using a Valkyrie ID, and map it to a Valkyrie Resource

Parameters:

  • id (Valkyrie::ID, String)

Returns:

  • (Valkyrie::Resource)

Raises:

  • (Valkyrie::Persistence::ObjectNotFoundError)

46
47
48
# File 'lib/wings/valkyrie/query_service.rb', line 46

def find_by(id:)
  find_by_alternate_identifier(alternate_identifier: id)
end

#find_by_alternate_identifier(alternate_identifier:, use_valkyrie: true) ⇒ Valkyrie::Resource

Find a record using an alternate ID, and map it to a Valkyrie Resource

Parameters:

  • id (Valkyrie::ID, String)
  • optionally (boolean)

    return ActiveFedora object/errors

Returns:

  • (Valkyrie::Resource)

Raises:

  • (Valkyrie::Persistence::ObjectNotFoundError)

106
107
108
109
110
111
112
113
114
115
116
# File 'lib/wings/valkyrie/query_service.rb', line 106

def find_by_alternate_identifier(alternate_identifier:, use_valkyrie: true)
  raise(ArgumentError, 'id must be a Valkyrie::ID') unless
    alternate_identifier.respond_to?(:to_str)

  af_object = ActiveFedora::Base.find(alternate_identifier.to_s)

  use_valkyrie ? resource_factory.to_resource(object: af_object) : af_object
rescue ActiveFedora::ObjectNotFoundError, Ldp::Gone => err
  raise err unless use_valkyrie
  raise ::Valkyrie::Persistence::ObjectNotFoundError
end

#find_inverse_references_by(resource: nil, id: nil, model: nil, property:) ⇒ Array<Valkyrie::Resource>

Get all resources which link to a resource or id with a given property.

Parameters:

  • resource (Valkyrie::Resource) (defaults to: nil)

    The resource which is being referenced by other resources.

  • resource (Valkyrie::ID) (defaults to: nil)

    The id of the resource which is being referenced by other resources.

  • property (Symbol)

    The property which, on other resources, is referencing the given `resource`. Note: the property needs to be indexed as a `*_ssim` field and indexing either ActiveFedora IDs or full URIs

Returns:

  • (Array<Valkyrie::Resource>)

    All resources in the persistence backend which have the ID of the given `resource` in their `property` property. Not in order.

Raises:

  • (ArgumentError)

    Raised when the ID is not in the persistence backend.


166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/wings/valkyrie/query_service.rb', line 166

def find_inverse_references_by(resource: nil, id: nil, model: nil, property:)
  raise ArgumentError, "Provide resource or id" unless resource || id
  id ||= resource.id
  raise ArgumentError, "Resource has no id; is it persisted?" unless id

  active_fedora_model = model ? model_class_for(model) : ActiveFedora::Base

  uri = active_fedora_model.id_to_uri(id.to_s)
  active_fedora_model.where("+(#{property}_ssim: \"#{uri}\" OR #{property}_ssim: \"#{id}\")").map do |obj|
    resource_factory.to_resource(object: obj)
  end
end

#find_many_by_ids(ids:) ⇒ Array<Valkyrie::Resource>

Note:

ignores non-existent ids.

Find an array of record using Valkyrie IDs, and map them to Valkyrie Resources maintaining order based on given ids

Parameters:

  • ids (Array<Valkyrie::ID, String>)

Returns:

  • (Array<Valkyrie::Resource>)

Raises:

  • (ArgumentError)

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/wings/valkyrie/query_service.rb', line 82

def find_many_by_ids(ids:)
  ids.all? { |i| i.respond_to?(:to_str) } ||
    raise(ArgumentError, 'id must be a Valkyrie::ID')

  return enum_for(:find_many_by_ids, ids: ids) unless block_given?

  ids.map(&:to_s).uniq.each do |id|
    begin
      af_object = ActiveFedora::Base.find(id)
      yield resource_factory.to_resource(object: af_object)
    rescue ::ActiveFedora::ObjectNotFoundError, Ldp::Gone
      next
    end
  end
end

#find_members(resource:, model: nil) ⇒ Array<Valkyrie::Resource>

Find all members of a given resource, and map to Valkyrie Resources

Parameters:

  • resource (Valkyrie::Resource)
  • model (Class) (defaults to: nil)

Returns:

  • (Array<Valkyrie::Resource>)

125
126
127
128
129
130
131
132
# File 'lib/wings/valkyrie/query_service.rb', line 125

def find_members(resource:, model: nil)
  return [] if resource.try(:member_ids).blank?
  return find_many_by_ids(ids: resource.member_ids) unless model

  find_model = model_class_for(model)
  find_many_by_ids(ids: resource.member_ids)
    .select { |member_resource| model_class_for(member_resource.class) == find_model }
end

#find_parents(resource:) ⇒ Array<Valkyrie::Resource>

Find all parents of a given resource.

Parameters:

  • resource (Valkyrie::Resource)

    The resource whose parents are being searched for.

Returns:

  • (Array<Valkyrie::Resource>)

    All resources which are parents of the given `resource`. This means the resource's `id` appears in their `member_ids` array.


187
188
189
190
191
# File 'lib/wings/valkyrie/query_service.rb', line 187

def find_parents(resource:)
  ActiveFedora::Base.where("member_ids_ssim: \"#{resource.id}\"").map do |obj|
    resource_factory.to_resource(object: obj)
  end
end

#find_references_by(resource:, property:, model: nil) ⇒ Array<Valkyrie::Resource>

Find the Valkyrie Resources referenced by another Valkyrie Resource

Parameters:

  • resource (<Valkyrie::Resource>)
  • property (Symbol)

    the property holding the references to another resource

Returns:

  • (Array<Valkyrie::Resource>)

140
141
142
143
144
145
146
147
148
149
150
# File 'lib/wings/valkyrie/query_service.rb', line 140

def find_references_by(resource:, property:, model: nil)
  return find_many_by_ids(ids: Array(resource.send(property))) unless model

  results = resource.public_send(property).map do |reference|
    resource_factory.to_resource(object: ::ActiveFedora::Base.find(reference))
  end

  results.select { |r| r.class.name == model.name }
rescue ActiveFedora::ObjectNotFoundError
  []
end