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)

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

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)

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

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.


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

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

  property = Hyrax.config.admin_set_predicate.qname.last if property.to_sym == :admin_set_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
# 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|
    af_object = ActiveFedora::Base.find(id)
    yield resource_factory.to_resource(object: af_object)
  rescue ::ActiveFedora::ObjectNotFoundError, Ldp::Gone
    next
  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>)

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

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.


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

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>)

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

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