Class: Otu::Filter

Inherits:
Queries::Query show all
Defined in:
lib/queries/otu/filter.rb

Overview

TODO: Unify all and filter

Instance Attribute Summary collapse

Attributes inherited from Queries::Query

#dynamic_limit, #options, #project_id, #query_string, #terms

Instance Method Summary collapse

Methods inherited from Queries::Query

#alphabetic_strings, #attribute_exact_facet, #autocomplete, #autocomplete_cached, #autocomplete_cached_wildcard_anywhere, #autocomplete_common_name_exact, #autocomplete_common_name_like, #autocomplete_exact_id, #autocomplete_exactly_named, #autocomplete_named, #autocomplete_ordered_wildcard_pieces_in_cached, #build_terms, #cached, #combine_or_clauses, #common_name_name, #common_name_table, #common_name_wild_pieces, #end_wildcard, #exactly_named, #fragments, #integers, #match_ordered_wildcard_pieces_in_cached, #match_wildcard_end_in_cached, #match_wildcard_in_cached, #named, #no_terms?, #only_ids, #only_integers?, #parent, #parent_child_join, #parent_child_where, #pieces, #scope, #start_and_end_wildcard, #start_wildcard, #wildcard_pieces, #wildcard_wrapped_integers, #wildcard_wrapped_years, #with_cached, #with_cached_like, #with_id, #with_project_id, #year_letter, #years

Constructor Details

#initialize(params) ⇒ Filter

Returns a new instance of Filter

Parameters:

  • params (Hash)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/queries/otu/filter.rb', line 19

def initialize(params)
  params.reject! { |_k, v| v.blank? }
  @and_or_select = params[:and_or_select]

  @geographic_area_ids = params[:geographic_area_ids]
  @shape = params[:drawn_area_shape]
  @selection_objects = params[:selection_objects] || ['CollectionObject', 'AssertedDistribution']
  @author_ids = params[:author_ids]
  @verbatim_author = params[:verbatim_author]

  @rank_class = params[:rank_class]
  @descendants = params[:descendants]

  @name = params[:name]

  @taxon_name_id = params[:taxon_name_id]
  @taxon_name_ids = params[:taxon_name_ids] || []
  @otu_id = params[:otu_id]
  @otu_ids = params[:otu_ids] || []

  @biological_association_ids = params[:biological_association_ids] || []

  @taxon_name_classification_ids = params[:taxon_name_classification_ids] || []
  @taxon_name_relationship_ids = params[:taxon_name_relationship_ids] || []
  @asserted_distribution_ids = params[:asserted_distribution_ids] || []
  @project_id = params[:project_id]
end

Instance Attribute Details

#and_or_selectObject

Returns the value of attribute and_or_select



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

def and_or_select
  @and_or_select
end

#asserted_distribution_idsObject

Returns the value of attribute asserted_distribution_ids



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def asserted_distribution_ids
  @asserted_distribution_ids
end

#author_idsObject

Returns the value of attribute author_ids



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

def author_ids
  @author_ids
end

#biological_association_idsObject

Returns the value of attribute biological_association_ids



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def biological_association_ids
  @biological_association_ids
end

#descendantsObject

Returns the value of attribute descendants



9
10
11
# File 'lib/queries/otu/filter.rb', line 9

def descendants
  @descendants
end

#geographic_area_idsObject

Query variables



7
8
9
# File 'lib/queries/otu/filter.rb', line 7

def geographic_area_ids
  @geographic_area_ids
end

#nameObject

Returns the value of attribute name



16
17
18
# File 'lib/queries/otu/filter.rb', line 16

def name
  @name
end

#otu_idObject

Returns the value of attribute otu_id



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def otu_id
  @otu_id
end

#otu_idsObject

Returns the value of attribute otu_ids



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def otu_ids
  @otu_ids
end

#rank_classObject

Returns the value of attribute rank_class



9
10
11
# File 'lib/queries/otu/filter.rb', line 9

def rank_class
  @rank_class
end

#selection_objectsObject

Returns the value of attribute selection_objects



8
9
10
# File 'lib/queries/otu/filter.rb', line 8

def selection_objects
  @selection_objects
end

#shapeObject

Query variables



7
8
9
# File 'lib/queries/otu/filter.rb', line 7

def shape
  @shape
end

#taxon_name_classification_idsObject

Returns the value of attribute taxon_name_classification_ids



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def taxon_name_classification_ids
  @taxon_name_classification_ids
end

#taxon_name_idObject

Returns the value of attribute taxon_name_id



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def taxon_name_id
  @taxon_name_id
end

#taxon_name_idsObject

Returns the value of attribute taxon_name_ids



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def taxon_name_ids
  @taxon_name_ids
end

#taxon_name_relationship_idsObject

Returns the value of attribute taxon_name_relationship_ids



13
14
15
# File 'lib/queries/otu/filter.rb', line 13

def taxon_name_relationship_ids
  @taxon_name_relationship_ids
end

#verbatim_authorObject

was verbatim_author_string



12
13
14
# File 'lib/queries/otu/filter.rb', line 12

def verbatim_author
  @verbatim_author
end

Instance Method Details

#allActiveRecord::Relation

Returns:

  • (ActiveRecord::Relation)


424
425
426
427
428
429
430
431
432
433
434
435
436
# File 'lib/queries/otu/filter.rb', line 424

def all
  a = and_clauses
  b = merge_clauses
  if a && b
    b.where(a).distinct
  elsif a
    ::Otu.where(a).distinct
  elsif b
    b.distinct
  else
    ::Otu.all
  end
end

#and_clausesActiveRecord::Relation?

Returns:

  • (ActiveRecord::Relation, nil)


385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/queries/otu/filter.rb', line 385

def and_clauses
  clauses = [
    matching_taxon_name_ids,
    matching_otu_ids,
    matching_name,

    # matching_verbatim_author
    # Queries::Annotator.annotator_params(options, ::Citation),
  ].compact

  return nil if clauses.empty?

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

#applied_scopesArray

Returns determine which scopes to apply based on parameters provided

Returns:

  • (Array)

    determine which scopes to apply based on parameters provided



244
245
246
247
248
249
250
251
252
# File 'lib/queries/otu/filter.rb', line 244

def applied_scopes
  scopes = []
  scopes.push :geographic_area_scope if area_set?
  scopes.push :shape_scope if shape_set?
  scopes.push :nomen_scope if nomen_set?
  scopes.push :author_scope if author_set?
  scopes.push :verbatim_scope if verbatim_set?
  scopes
end

#area_set?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/queries/otu/filter.rb', line 83

def area_set?
  !geographic_area_ids.nil?
end

#author_scopeScope

Returns 1. find all selected taxon name authors

  1. find all taxon_names which are associated with result #1

  2. find all otus which are associated with result #2

Returns:

  • (Scope)
    1. find all selected taxon name authors

    2. find all taxon_names which are associated with result #1

    3. find all otus which are associated with result #2



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/queries/otu/filter.rb', line 198

def author_scope

  r = ::Role.arel_table

  case and_or_select
  when '_or_', nil

    c = r[:person_id].eq_any(author_ids).and(r[:type].eq('TaxonNameAuthor'))
    ::Otu.joins(taxon_name: [:roles]).where(c.to_sql).distinct

  when '_and_'
    table_alias = 'tna' # alias for 'TaxonNameAuthor'

    o = ::Otu.arel_table
    t = ::TaxonName.arel_table

    b = o.project(o[Arel.star]).from(o)
      .join(t)
      .on(t['id'].eq(o['taxon_name_id']))
      .join(r).on(
        r['role_object_id'].eq(t['id']).and(
          r['type'].eq('TaxonNameAuthor')
        )
    )

    author_ids.each_with_index do |person_id, i|
      x = r.alias("#{table_alias}_#{i}")
      b = b.join(x).on(
        x['role_object_id'].eq(t['id']),
        x['type'].eq('TaxonNameAuthor'),
        x['person_id'].eq(person_id)
      )
    end

    b = b.group(o['id']).having(r['person_id'].count.gteq(author_ids.count))
    b = b.as("z_#{table_alias}")

    # noinspection RubyResolve
    ::Otu.joins(Arel::Nodes::InnerJoin.new(b, Arel::Nodes::On.new(b['id'].eq(o['id']))))
  end
end

#author_set?Boolean

Returns:

  • (Boolean)


88
89
90
91
92
93
94
95
# File 'lib/queries/otu/filter.rb', line 88

def author_set?
  case author_ids
  when nil
    false
  else
    author_ids.count > 0
  end
end

#biological_associations_tableObject



51
52
53
# File 'lib/queries/otu/filter.rb', line 51

def biological_associations_table
  ::BiologicalAssociation.arel_table
end

#geographic_area_scopeScope

This could be simplified if the AJAX selector returned a geographic_item_id rather than a geographic_area_id

  1. find all geographic_items in area(s)/shape.

  2. find all georeferences which are associated with result #1

  3. find all collecting_events which are associated with result #2

  4. find all collection_objects which are associated with result #3

  5. find all asserted_distrubutions which are associated with result #1

  6. find all otus which are associated with result #4 plus result #5

Returns:

  • (Scope)


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/queries/otu/filter.rb', line 138

def geographic_area_scope
  target_geographic_item_ids = []

  geographic_area_ids.each do |ga_id|
    target_geographic_item_ids.push(
      ::GeographicArea.joins(:geographic_items).find(ga_id).default_geographic_item.id
    )
  end

  gi_sql = ::GeographicItem.contained_by_where_sql(target_geographic_item_ids)

  ::Otu.where(id: (::Otu.joins(:asserted_distributions)
    .where(asserted_distributions: {id: ::AssertedDistribution.joins(:geographic_items)
    .where(gi_sql).distinct})) +
  (::Otu.joins(:collection_objects)
    .where(collection_objects: {id: ::CollectionObject.joins(:geographic_items)
    .where(gi_sql).distinct})).distinct)
end

#ids_for_otuArray

Returns of otu_id

Returns:

  • (Array)

    of otu_id



67
68
69
# File 'lib/queries/otu/filter.rb', line 67

def ids_for_otu
  ([otu_id] + otu_ids).compact.uniq
end

#ids_for_taxon_nameArray

Returns of taxon_name.id

Returns:

  • (Array)

    of taxon_name.id



78
79
80
# File 'lib/queries/otu/filter.rb', line 78

def ids_for_taxon_name
  ([taxon_name_id] + taxon_name_ids).compact.uniq
end

#matching_asserted_distribution_idsObject



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/queries/otu/filter.rb', line 359

def matching_asserted_distribution_ids
  return nil if asserted_distribution_ids.empty?
  o = table
  ad = ::AssertedDistribution.arel_table

  a = o.alias("a_")
  b = o.project(a[Arel.star]).from(a)

  c = ad.alias('ad1')

  b = b.join(c, Arel::Nodes::OuterJoin)
    .on(
      a[:id].eq(c[:otu_id])
  )

  e = c[:otu_id].not_eq(nil)
  f = c[:id].eq_any(asserted_distribution_ids)

  b = b.where(e.and(f))
  b = b.group(a['id'])
  b = b.as('z4_')

  ::Otu.joins(Arel::Nodes::InnerJoin.new(b, Arel::Nodes::On.new(b['id'].eq(o['id']))))
end

#matching_biological_association_idsObject



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/queries/otu/filter.rb', line 298

def matching_biological_association_ids
  return nil if biological_association_ids.empty?
  o = table
  ba = biological_associations_table

  a = o.alias("a_")
  b = o.project(a[Arel.star]).from(a)

  c = ba.alias('b1')
  d = ba.alias('b2')

  b = b.join(c, Arel::Nodes::OuterJoin)
    .on(
      a[:id].eq(c[:biological_association_subject_id])
    .and(c[:biological_association_subject_type].eq('Otu'))
  )

  b = b.join(d, Arel::Nodes::OuterJoin)
    .on(
      a[:id].eq(d[:biological_association_object_id])
    .and(d[:biological_association_object_type].eq('Otu'))
  )

  e = c[:biological_association_subject_id].not_eq(nil)
  f = d[:biological_association_object_id].not_eq(nil)

  g = c[:id].eq_any(biological_association_ids)
  h = d[:id].eq_any(biological_association_ids)

  b = b.where(e.or(f).and(g.or(h)))
  b = b.group(a['id'])
  b = b.as('z2_')

  ::Otu.joins(Arel::Nodes::InnerJoin.new(b, Arel::Nodes::On.new(b['id'].eq(o['id']))))
end

#matching_nameObject



60
61
62
63
# File 'lib/queries/otu/filter.rb', line 60

def matching_name
  a = name
  a.blank? ? nil : table[:name].eq(a)
end

#matching_otu_idsObject



55
56
57
58
# File 'lib/queries/otu/filter.rb', line 55

def matching_otu_ids
  a = ids_for_otu
  a.empty? ? nil : table[:id].eq_any(a)
end

#matching_taxon_name_classification_idsObject



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/queries/otu/filter.rb', line 334

def matching_taxon_name_classification_ids
  return nil if taxon_name_classification_ids.empty?
  o = table
  tnc = ::TaxonNameClassification.arel_table

  a = o.alias("a_")
  b = o.project(a[Arel.star]).from(a)

  c = tnc.alias('tnc1')

  b = b.join(c, Arel::Nodes::OuterJoin)
    .on(
      a[:taxon_name_id].eq(c[:taxon_name_id])
  )

  e = c[:id].not_eq(nil)
  f = c[:id].eq_any(taxon_name_classification_ids)

  b = b.where(e.and(f))
  b = b.group(a['id'])
  b = b.as('z3_')

  ::Otu.joins(Arel::Nodes::InnerJoin.new(b, Arel::Nodes::On.new(b['id'].eq(o['id']))))
end

#matching_taxon_name_idsObject



71
72
73
74
# File 'lib/queries/otu/filter.rb', line 71

def matching_taxon_name_ids
  a = ids_for_taxon_name
  a.empty? ? nil : table[:taxon_name_id].eq_any(a)
end

#matching_taxon_name_relationship_idsObject



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/queries/otu/filter.rb', line 264

def matching_taxon_name_relationship_ids
  return nil if taxon_name_relationship_ids.empty?
  o = table
  ba = ::TaxonNameRelationship.arel_table

  a = o.alias("a_")
  b = o.project(a[Arel.star]).from(a)

  c = ba.alias('b1')
  d = ba.alias('b2')

  b = b.join(c, Arel::Nodes::OuterJoin)
    .on(
      a[:taxon_name_id].eq(c[:subject_taxon_name_id])
  )

  b = b.join(d, Arel::Nodes::OuterJoin)
    .on(
      a[:id].eq(d[:object_taxon_name_id])
  )

  e = c[:subject_taxon_name_id].not_eq(nil)
  f = d[:object_taxon_name_id].not_eq(nil)

  g = c[:id].eq_any(taxon_name_relationship_ids)
  h = d[:id].eq_any(taxon_name_relationship_ids)

  b = b.where(e.or(f).and(g.or(h)))
  b = b.group(a['id'])
  b = b.as('z1_')

  ::Otu.joins(Arel::Nodes::InnerJoin.new(b, Arel::Nodes::On.new(b['id'].eq(o['id']))))
end

#merge_clausesObject



404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/queries/otu/filter.rb', line 404

def merge_clauses
  clauses = [
    matching_biological_association_ids,
    matching_asserted_distribution_ids,
    matching_taxon_name_classification_ids,
    matching_taxon_name_relationship_ids

    # matching_verbatim_author
  ].compact

  return nil if clauses.empty?

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

#nomen_scopeScope

Returns:

  • (Scope)


180
181
182
183
184
185
186
187
# File 'lib/queries/otu/filter.rb', line 180

def nomen_scope
  scope1 = ::Otu.joins(:taxon_name).where(taxon_name_id: taxon_name_id)
  scope = scope1
  if scope1.any?
    scope = ::Otu.self_and_descendants_of(scope1.first.id, rank_class) if with_descendants?
  end
  scope
end

#nomen_set?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/queries/otu/filter.rb', line 98

def nomen_set?
  !taxon_name_id.nil?
end

#resultScope

Returns:

  • (Scope)


119
120
121
122
123
124
125
126
# File 'lib/queries/otu/filter.rb', line 119

def result
  return ::Otu.none if applied_scopes.empty?
  a = ::Otu.all
  applied_scopes.each do |scope|
    a = a.merge(self.send(scope))
  end
  a
end

#shape_scopeScope

  1. find all collection_objects which are associated with the shape provided.

  2. find all asserted_distrubutions which are associated the shape provided.

  3. find all otus which are associated with result #1 plus result #2

Returns:

  • (Scope)


163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/queries/otu/filter.rb', line 163

def shape_scope
  ::Otu.where(id: (::Otu.joins(:asserted_distributions)
    .where(asserted_distributions: {id: ::GeographicItem.gather_map_data(
      shape,
      'AssertedDistribution',
      project_id)
    .distinct}) +
  ::Otu.joins(:collection_objects)
    .where(collection_objects: {id: ::GeographicItem.gather_map_data(
      shape,
      'CollectionObject',
      project_id)
    .distinct}))
    .uniq)
end

#shape_set?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/queries/otu/filter.rb', line 108

def shape_set?
  !shape.nil?
end

#tableObject



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

def table
  ::Otu.arel_table
end

#verbatim_scopeScope

Returns:

  • (Scope)


190
191
192
# File 'lib/queries/otu/filter.rb', line 190

def verbatim_scope
  ::Otu.joins(:taxon_name).where('taxon_names.cached_author_year ILIKE ?', "%#{verbatim_author}%")
end

#verbatim_set?Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/queries/otu/filter.rb', line 103

def verbatim_set?
  !verbatim_author.blank?
end

#with_descendants?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/queries/otu/filter.rb', line 113

def with_descendants?
  !descendants.nil?
end