Class: Queries::Image::Filter

Inherits:
Object
  • Object
show all
Includes:
Concerns::Identifiers, Concerns::Tags, Concerns::Users
Defined in:
lib/queries/image/filter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params) ⇒ Filter

Returns a new instance of Filter.

Parameters:

  • params (Hash)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/queries/image/filter.rb', line 82

def initialize(params)
  params.reject!{ |_k, v| v.blank? } # dump all entries with empty values

  @otu_id = params[:otu_id]
  @otu_scope = params[:otu_scope]&.map(&:to_sym)
  @collection_object_id = params[:collection_object_id]
  @collecting_event_id = params[:collecting_event_id]
  @image_id = params[:image_id]
  @biocuration_class_id = params[:biocuration_class_id]
  @sled_image_id = params[:sled_image_id]
  @sqed_depiction_id = params[:sqed_depiction_id]
  @taxon_name_id = params[:taxon_name_id]
  @ancestor_id_target = params[:ancestor_id_target]

  @depiction = (params[:depiction]&.downcase == 'true' ? true : false) if !params[:depiction].nil?

  set_identifier(params)
  set_tags_params(params)
  set_user_dates(params)
end

Instance Attribute Details

#ancestor_id_targetArray

Only used when `ancestor_id` provided

Returns:

  • (Array)

    one or both of 'Otu', 'CollectionObject', defaults to both if nothing provided



69
70
71
# File 'lib/queries/image/filter.rb', line 69

def ancestor_id_target
  @ancestor_id_target
end

#biocuration_class_idArray

Returns of biocuration_class ids.

Returns:

  • (Array)

    of biocuration_class ids



47
48
49
# File 'lib/queries/image/filter.rb', line 47

def biocuration_class_id
  @biocuration_class_id
end

#collecting_event_idArray

Returns only return objects with this collecting event ID.

Returns:

  • (Array)

    only return objects with this collecting event ID



10
11
12
# File 'lib/queries/image/filter.rb', line 10

def collecting_event_id
  @collecting_event_id
end

#collection_object_idArray

Returns a list of Collection object ids, matches one ot one only.

Returns:

  • (Array)

    a list of Collection object ids, matches one ot one only



14
15
16
# File 'lib/queries/image/filter.rb', line 14

def collection_object_id
  @collection_object_id
end

#depictionBoolean?

Returns true - image is used (in a depiction) false - image is not used nil - either.

Returns:

  • (Boolean, nil)

    true - image is used (in a depiction) false - image is not used nil - either



59
60
61
# File 'lib/queries/image/filter.rb', line 59

def depiction
  @depiction
end

#image_idArray

Returns:

  • (Array)


43
44
45
# File 'lib/queries/image/filter.rb', line 43

def image_id
  @image_id
end

#otu_idArray

Returns a list of Otu ids, matches one ot one only.

Parameters:

  • otu_id (Array, Integer)

    `otu_id=1` or `otu_id[]=1`

Returns:

  • (Array)

    a list of Otu ids, matches one ot one only



20
21
22
# File 'lib/queries/image/filter.rb', line 20

def otu_id
  @otu_id
end

#otu_scopeArray

A sub scope of sorts. Purpose is to gather all images possible under an OTU that are of an OTU, CollectionObject or Observation.

!! Must be used with an otu_id !!

Parameters:

  • otu_scope

    options

    :all (default, includes all below)
    
    :otu (those on the OTU)
    :otu_observations (those on just the OTU)
    :collection_object_observations (those on just those determined as the OTU)
    :collection_objects (those on just those on the collection objects)
    :type_material (those on CollectionObjects that have TaxonName used in OTU)
    :type_material_observations (those on CollectionObjects that have TaxonName used in OTU)
    
    :coordinate_otus  If present adds both.  Use downstream substraction to to diffs of with/out?
    

Returns:

  • (Array)


40
41
42
# File 'lib/queries/image/filter.rb', line 40

def otu_scope
  @otu_scope
end

#sled_image_idArray

Returns:

  • (Array)


50
51
52
# File 'lib/queries/image/filter.rb', line 50

def sled_image_id
  @sled_image_id
end

#sqed_depiction_idArray

Returns:

  • (Array)


53
54
55
# File 'lib/queries/image/filter.rb', line 53

def sqed_depiction_id
  @sqed_depiction_id
end

#taxon_name_idProtonym.id?

Return all images depicting an Otu that is self or descendant linked to this TaxonName

Returns:

  • (Protonym.id, nil)

    return all images depicting an Otu that is self or descendant linked to this TaxonName



64
65
66
# File 'lib/queries/image/filter.rb', line 64

def taxon_name_id
  @taxon_name_id
end

Instance Method Details

#allActiveRecord::Relation

Returns:

  • (ActiveRecord::Relation)


358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/queries/image/filter.rb', line 358

def all
  a = and_clauses
  b = merge_clauses
  # q = nil
  if a && b
    q = b.where(a).distinct
  elsif a
    q = ::Image.where(a).distinct
  elsif b
    q = b.distinct
  else
    q = ::Image.all
  end

  q
end

#ancestors_facetObject



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/queries/image/filter.rb', line 409

def ancestors_facet
  #  Image -> Depictions -> Otu -> TaxonName -> Ancestors
  return nil if taxon_name_id.empty?

  h = Arel::Table.new(:taxon_name_hierarchies)
  t = ::TaxonName.arel_table

  j1, j2, q1, q2 = nil, nil, nil, nil

  if ancestor_id_target.include?('Otu')
    a = otu_table.alias('oj1')
    b = t.alias('tj1')
    h_alias = h.alias('th1')

    j1 = table
      .join(depiction_table, Arel::Nodes::InnerJoin).on(table[:id].eq(depiction_table[:image_id]))
      .join(a, Arel::Nodes::InnerJoin).on( depiction_table[:depiction_object_id].eq(a[:id]).and( depiction_table[:depiction_object_type].eq('Otu') ))
      .join(b, Arel::Nodes::InnerJoin).on( a[:taxon_name_id].eq(b[:id]))
      .join(h_alias, Arel::Nodes::InnerJoin).on(b[:id].eq(h_alias[:descendant_id]))

    z = h_alias[:ancestor_id].eq_any(taxon_name_id)
    q1 = ::Image.joins(j1.join_sources).where(z)
  end

  if ancestor_id_target.include?('CollectionObject')
    a = otu_table.alias('oj2')
    b = t.alias('tj2')
    h_alias = h.alias('th2')

    j2 = table
      .join(depiction_table, Arel::Nodes::InnerJoin).on(table[:id].eq(depiction_table[:image_id]))
      .join(collection_object_table, Arel::Nodes::InnerJoin).on( depiction_table[:depiction_object_id].eq(collection_object_table[:id]).and( depiction_table[:depiction_object_type].eq('CollectionObject') ))
      .join(taxon_determination_table, Arel::Nodes::InnerJoin).on( collection_object_table[:id].eq(taxon_determination_table[:biological_collection_object_id]) )
      .join(a, Arel::Nodes::InnerJoin).on(  taxon_determination_table[:otu_id].eq(a[:id]) )
      .join(b, Arel::Nodes::InnerJoin).on( a[:taxon_name_id].eq(b[:id]))
      .join(h_alias, Arel::Nodes::InnerJoin).on(b[:id].eq(h_alias[:descendant_id]))

    z = h_alias[:ancestor_id].eq_any(taxon_name_id)
    q2 = ::Image.joins(j2.join_sources).where(z)
  end

  if q1 && q2
    ::Image.from("((#{q1.to_sql}) UNION (#{q2.to_sql})) as images")
  elsif q1
    q1
  else
    q2
  end

  #  if validity == true
  #    z = z.and(t[:cached_valid_taxon_name_id].eq(t[:id]))
  #  elsif validity == false
  #    z = z.and(t[:cached_valid_taxon_name_id].not_eq(t[:id]))
  #  end

  # if current_determinations == true
  #   z = z.and(taxon_determination_table[:position].eq(1))
  # elsif current_determinations == false
  #   z = z.and(taxon_determination_table[:position].gt(1))
  # end

end

#and_clausesActiveRecord::Relation

Returns:

  • (ActiveRecord::Relation)


294
295
296
297
298
299
300
301
302
303
304
# File 'lib/queries/image/filter.rb', line 294

def and_clauses
  clauses = base_and_clauses

  return nil if clauses.empty?

  a = clauses.shift
  clauses.each do |b|
    a = a.and(b)
  end
  a
end

#base_and_clausesArray

Returns:

  • (Array)


307
308
309
310
311
312
313
314
315
316
317
# File 'lib/queries/image/filter.rb', line 307

def base_and_clauses
  clauses = [
    image_facet
  ]

  clauses += [
    #type_facet,
  ]
  clauses.compact!
  clauses
end

#base_merge_clausesObject



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/queries/image/filter.rb', line 319

def base_merge_clauses
  clauses = []
  #  clauses += collecting_event_merge_clauses + collecting_event_and_clauses

  clauses += [
    otu_facet,
    otu_scope_facet,
    build_depiction_facet('CollectionObject', collection_object_id),
    build_depiction_facet('CollectingEvent', collecting_event_id),
    #    type_material_facet,
    #    type_material_type_facet,
    ancestors_facet,
    keyword_id_facet,  # See Queries::Concerns::Tags
    created_updated_facet, # See Queries::Concerns::Users
    #   identifier_between_facet,
    #   identifier_facet,
    #   identifier_namespace_facet,
    sqed_depiction_facet,
    sled_image_facet,
    biocuration_facet,
    depiction_facet,
  ]

  clauses.compact!
  clauses
end

#base_queryObject



155
156
157
# File 'lib/queries/image/filter.rb', line 155

def base_query
  ::Image.select('images.*')
end

#biocuration_facetObject



184
185
186
187
188
189
190
# File 'lib/queries/image/filter.rb', line 184

def biocuration_facet
  return nil if biocuration_class_id.empty?
  ::Image.joins(collection_objects: [:depictions]).merge(
    ::CollectionObject::BiologicalCollectionObject.joins(:biocuration_classifications)
    .where(biocuration_classifications: {biocuration_class_id: biocuration_class_id})
  )
end

#build_depiction_facet(kind, ids) ⇒ Object



404
405
406
407
# File 'lib/queries/image/filter.rb', line 404

def build_depiction_facet(kind, ids)
  return nil if ids.empty?
  ::Image.joins(:depictions).where(depictions: {depiction_object_id: ids, depiction_object_type: kind})
end

#collecting_event_tableArel::Table

Returns:

  • (Arel::Table)


160
161
162
# File 'lib/queries/image/filter.rb', line 160

def collecting_event_table
  ::CollectingEvent.arel_table
end

#collection_object_tableArel::Table

Returns:

  • (Arel::Table)


170
171
172
# File 'lib/queries/image/filter.rb', line 170

def collection_object_table
  ::CollectionObject.arel_table
end

#coordinate_otu_idsObject



219
220
221
222
223
224
225
# File 'lib/queries/image/filter.rb', line 219

def coordinate_otu_ids
  ids = []
  otu_id.each do |id|
    ids += ::Otu.coordinate_otus(id).pluck(:id)
  end
  ids.uniq
end

#depiction_facetObject



192
193
194
195
196
# File 'lib/queries/image/filter.rb', line 192

def depiction_facet
  return nil if depiction.nil?
  subquery = ::Image.joins(:depictions).where(table[:id].eq(depiction_table[:image_id])).arel.exists
  ::Image.where(depiction == true ? subquery : subquery.not)
end

#depiction_tableArel::Table

Returns:

  • (Arel::Table)


180
181
182
# File 'lib/queries/image/filter.rb', line 180

def depiction_table
  ::Depiction.arel_table
end

#image_facetObject



399
400
401
402
# File 'lib/queries/image/filter.rb', line 399

def image_facet
  return nil if image_id.empty?
  table[:id].eq_any(image_id)
end

#merge_clausesActiveRecord::Relation

Returns:

  • (ActiveRecord::Relation)


347
348
349
350
351
352
353
354
355
# File 'lib/queries/image/filter.rb', line 347

def merge_clauses
  clauses = base_merge_clauses
  return nil if clauses.empty?
  a = clauses.shift
  clauses.each do |b|
    a = a.merge(b)
  end
  a
end

#otu_facetObject



214
215
216
217
# File 'lib/queries/image/filter.rb', line 214

def otu_facet
  return nil if otu_id.empty? || !otu_scope.empty?
  build_depiction_facet('Otu', otu_id)
end

#otu_facet_collection_object_observations(otu_ids) ⇒ Object



282
283
284
285
286
# File 'lib/queries/image/filter.rb', line 282

def otu_facet_collection_object_observations(otu_ids)
  ::Image.joins(:observations)
    .joins('INNER JOIN taxon_determinations on taxon_determinations.biological_collection_object_id = observations.observation_object_id')
    .where(taxon_determinations: {otu_id: otu_ids}, observations: {observation_object_type: 'CollectionObject'})
end

#otu_facet_collection_objects(otu_ids) ⇒ Object



277
278
279
280
# File 'lib/queries/image/filter.rb', line 277

def otu_facet_collection_objects(otu_ids)
  ::Image.joins(collection_objects: [:taxon_determinations])
    .where(taxon_determinations: {otu_id: otu_ids})
end

#otu_facet_otu_observations(otu_ids) ⇒ Object



288
289
290
291
# File 'lib/queries/image/filter.rb', line 288

def otu_facet_otu_observations(otu_ids)
  ::Image.joins(:observations)
    .where(observations: {observation_object_id: otu_ids, observation_object_type: 'Otu'})
end

#otu_facet_otus(otu_ids) ⇒ Object



273
274
275
# File 'lib/queries/image/filter.rb', line 273

def otu_facet_otus(otu_ids)
  ::Image.joins(:depictions).where(depictions: {depiction_object_type: 'Otu', depiction_object_id: otu_ids})
end

#otu_facet_type_material(otu_ids) ⇒ Object



268
269
270
271
# File 'lib/queries/image/filter.rb', line 268

def otu_facet_type_material(otu_ids)
  ::Image.joins(collection_objects: [type_materials: [protonym: [:otus]]])
    .where(otus: {id: otu_ids})
end

#otu_facet_type_material_observations(otu_ids) ⇒ Object



261
262
263
264
265
266
# File 'lib/queries/image/filter.rb', line 261

def otu_facet_type_material_observations(otu_ids)
  ::Image.joins(:observations)
    .joins("INNER JOIN type_materials on type_materials.collection_object_id = observations.observation_object_id AND observations.observation_object_type = 'CollectionObject'")
    .joins('INNER JOIN otus on otus.taxon_name_id = type_materials.protonym_id')
    .where(otus: {id: otu_ids})
end

#otu_scope_facetObject



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/queries/image/filter.rb', line 227

def otu_scope_facet
  return nil if otu_id.empty? || otu_scope.empty?

  otu_ids = otu_id
  otu_ids += coordinate_otu_ids if otu_scope.include?(:coordinate_otus)

  otu_ids.uniq!

  selected = []

  if otu_scope.include?(:all)
    selected = [
      :otu_facet_otus,
      :otu_facet_collection_objects,
      :otu_facet_otu_observations,
      :otu_facet_collection_object_observations,
      :otu_facet_type_material,
      :otu_facet_type_material_observations
    ]
  else
    selected.push :otu_facet_otus if otu_scope.include?(:otus)
    selected.push :otu_facet_collection_objects if otu_scope.include?(:collection_objects)
    selected.push :otu_facet_collection_object_observations if otu_scope.include?(:collection_object_observations)
    selected.push :otu_facet_otu_observations if otu_scope.include?(:otu_observations)
    selected.push :otu_facet_type_material if otu_scope.include?(:type_material)
    selected.push :otu_facet_type_material_observations if otu_scope.include?(:type_material_observations)
  end

  q = selected.collect{|a| '(' + send(a, otu_ids).to_sql + ')'}.join(' UNION ')

  d = ::Image.from('(' + q + ')' + ' as images')
  d
end

#otu_tableArel::Table

Returns:

  • (Arel::Table)


165
166
167
# File 'lib/queries/image/filter.rb', line 165

def otu_table
  ::Otu.arel_table
end

#sled_image_facetObject



204
205
206
207
# File 'lib/queries/image/filter.rb', line 204

def sled_image_facet
  return nil if sled_image_id.empty?
  ::Image.joins(:sled_image).where(sled_images: {id: sled_image_id})
end

#sqed_depiction_facetObject



209
210
211
212
# File 'lib/queries/image/filter.rb', line 209

def sqed_depiction_facet
  return nil if sqed_depiction_id.empty?
  ::Image.joins(depictions: [:sqed_depiction]).where(sqed_depictions: {id: sqed_depiction_id})
end

#tableArel::Table

Returns:

  • (Arel::Table)


146
147
148
# File 'lib/queries/image/filter.rb', line 146

def table
  ::Image.arel_table
end

#taxon_determination_tableArel::Table

Returns:

  • (Arel::Table)


151
152
153
# File 'lib/queries/image/filter.rb', line 151

def taxon_determination_table
  ::TaxonDetermination.arel_table
end

#type_facetObject

facet



199
200
201
202
# File 'lib/queries/image/filter.rb', line 199

def type_facet
  return nil if is_type.nil?
  table[:type].eq(collection_object_type)
end

#type_material_facetScope

Returns:

  • (Scope)


376
377
378
379
380
381
382
383
384
385
# File 'lib/queries/image/filter.rb', line 376

def type_material_facet
  return nil if type_specimen_taxon_name_id.nil?

  w = type_materials_table[:collection_object_id].eq(table[:id])
    .and( type_materials_table[:protonym_id].eq(type_specimen_taxon_name_id) )

  ::Image.where(
    ::TypeMaterial.where(w).arel.exists
  )
end

#type_material_type_facetScope

Returns:

  • (Scope)


388
389
390
391
392
393
394
395
396
397
# File 'lib/queries/image/filter.rb', line 388

def type_material_type_facet
  return nil if is_type.empty?

  w = type_materials_table[:collection_object_id].eq(table[:id])
    .and( type_materials_table[:type_type].eq_any(is_type) )

  ::Image.where(
    ::TypeMaterial.where(w).arel.exists
  )
end

#type_materials_tableArel::Table

Returns:

  • (Arel::Table)


175
176
177
# File 'lib/queries/image/filter.rb', line 175

def type_materials_table
  ::TypeMaterial.arel_table
end