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)


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

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]

  @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

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


415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/queries/otu/filter.rb', line 415

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)


377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/queries/otu/filter.rb', line 377

def and_clauses
  clauses = [
    matching_taxon_name_ids,
    matching_otu_ids,

    # 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



236
237
238
239
240
241
242
243
244
# File 'lib/queries/otu/filter.rb', line 236

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)


75
76
77
# File 'lib/queries/otu/filter.rb', line 75

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



190
191
192
193
194
195
196
197
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
# File 'lib/queries/otu/filter.rb', line 190

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)


80
81
82
83
84
85
86
87
# File 'lib/queries/otu/filter.rb', line 80

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

#biological_associations_tableObject



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

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)


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/queries/otu/filter.rb', line 130

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



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

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



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

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

#matching_asserted_distribution_idsObject



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/queries/otu/filter.rb', line 351

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



290
291
292
293
294
295
296
297
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
# File 'lib/queries/otu/filter.rb', line 290

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_otu_idsObject



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

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

#matching_taxon_name_classification_idsObject



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/queries/otu/filter.rb', line 326

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



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

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



256
257
258
259
260
261
262
263
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
# File 'lib/queries/otu/filter.rb', line 256

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



395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/queries/otu/filter.rb', line 395

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)


172
173
174
175
176
177
178
179
# File 'lib/queries/otu/filter.rb', line 172

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)


90
91
92
# File 'lib/queries/otu/filter.rb', line 90

def nomen_set?
  !taxon_name_id.nil?
end

#resultScope

Returns:

  • (Scope)


111
112
113
114
115
116
117
118
# File 'lib/queries/otu/filter.rb', line 111

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)


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/queries/otu/filter.rb', line 155

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)


100
101
102
# File 'lib/queries/otu/filter.rb', line 100

def shape_set?
  !shape.nil?
end

#tableObject



44
45
46
# File 'lib/queries/otu/filter.rb', line 44

def table
  ::Otu.arel_table
end

#verbatim_scopeScope

Returns:

  • (Scope)


182
183
184
# File 'lib/queries/otu/filter.rb', line 182

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

#verbatim_set?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/queries/otu/filter.rb', line 95

def verbatim_set?
  !verbatim_author.blank?
end

#with_descendants?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/queries/otu/filter.rb', line 105

def with_descendants?
  !descendants.nil?
end