Class: Queries::TaxonName::Filter

Inherits:
Query::Filter show all
Includes:
Concerns::Citations, Concerns::DataAttributes, Concerns::Depictions, Concerns::Notes, Concerns::Tags, Helpers
Defined in:
lib/queries/taxon_name/filter.rb

Constant Summary collapse

PARAMS =
[
  :ancestors,
  :ancestrify,
  :author,
  :author_exact,
  :authors,
  :collecting_event_id,
  :collection_object_id,
  :combinations,
  :combinationify,
  :descendants,
  :descendants_max_depth,
  :etymology,
  :leaves,
  :name,
  :name_exact,
  :nomenclature_code,
  :nomenclature_date,
  :nomenclature_group, # !! different than autocomplete
  :not_specified,
  :original_combination,
  :otu_id,
  :otus,
  :rank,
  :synonymify,
  :taxon_name_author_id_or,
  :taxon_name_id,
  :taxon_name_type,
  :type_metadata,
  :validify,
  :validity,
  :year,
  :year_end,
  :year_start,

  collection_object_id: [],
  collecting_event_id: [],
  combination_taxon_name_id: [],
  name: [],
  otu_id: [],
  parent_id: [],
  rank: [],
  taxon_name_author_id: [],
  taxon_name_classification: [],
  taxon_name_id: [],
  taxon_name_relationship: [
    :subject_taxon_name_id,
    :object_taxon_name_id,
    :type,
  ],
  taxon_name_relationship_type: [],
  type: [],
].freeze

Constants inherited from Query::Filter

Query::Filter::FILTER_QUERIES, Query::Filter::SUBQUERIES

Instance Attribute Summary collapse

Attributes inherited from Query::Filter

#api, #asserted_distribution_query, #biological_association_query, #biological_associations_graph_query, #collecting_event_query, #collection_object_query, #content_query, #controlled_vocabulary_term_query, #data_attribute_query, #descriptor_query, #extract_query, #image_query, #loan_query, #object_global_id, #observation_query, #otu_query, #page, #paginate, #params, #per, #person_query, #project_id, #recent, #taxon_name_query

Attributes inherited from Query

#query_string, #terms

Instance Method Summary collapse

Methods included from Helpers

#boolean_param

Methods inherited from Query::Filter

#all_and_clauses, #all_merge_clauses, #annotator_and_clauses, #annotator_merge_clauses, annotator_params, api_except_params, api_excluded_params, #attribute_exact_facet, #deep_permit, included_annotator_facets, inverted_subqueries, #object_global_id_facet, params, #permitted_params, #project_id_facet, #set_nested_queries, #shared_and_clauses, #subquery_vector

Methods inherited from Query

#alphabetic_strings, #alphanumeric_strings, base_name, #base_name, #base_query, #build_terms, #cached_facet, #end_wildcard, #levenshtein_distance, #match_ordered_wildcard_pieces_in_cached, #no_terms?, #referenced_klass, referenced_klass, #referenced_klass_except, #referenced_klass_intersection, #referenced_klass_union, #start_and_end_wildcard, #start_wildcard, #table, #wildcard_pieces

Constructor Details

#initialize(query_params) ⇒ Filter

Returns a new instance of Filter.

Parameters:

  • params (Params)

    as permitted via controller



287
288
289
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
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/queries/taxon_name/filter.rb', line 287

def initialize(query_params)
  super

  @ancestors = boolean_param(params, :ancestors)
  @ancestrify = boolean_param(params, :ancestrify)
  @author = params[:author]
  @author_exact = boolean_param(params, :author_exact)
  @authors = boolean_param(params, :authors)
  @collecting_event_id = params[:collecting_event_id]
  @collection_object_id = params[:collection_object_id]
  @combination_taxon_name_id = params[:combination_taxon_name_id]
  @combinations = boolean_param(params, :combinations)
  @combinationify = boolean_param(params, :combinationify)
  @descendants = boolean_param(params, :descendants)
  @descendants_max_depth = params[:descendants_max_depth]
  @etymology = boolean_param(params, :etymology)
  @geo_json = params[:geo_json]
  @leaves = boolean_param(params, :leaves)
  @name = params[:name]
  @name_exact = boolean_param(params, :name_exact)
  @nomenclature_date = boolean_param(params, :nomenclature_date)
  @nomenclature_code = params[:nomenclature_code] if params[:nomenclature_code].present?
  @nomenclature_group = params[:nomenclature_group] if params[:nomenclature_group].present?
  @not_specified = boolean_param(params, :not_specified)
  @otu_id = params[:otu_id]
  @otus = boolean_param(params, :otus)
  @original_combination = boolean_param(params, :original_combination)
  @parent_id = params[:parent_id]
  @rank = params[:rank]
  @sort = params[:sort]
  @synonymify = boolean_param(params, :synonymify)
  @taxon_name_author_id = params[:taxon_name_author_id]
  @taxon_name_author_id_or = boolean_param(params, :taxon_name_author_id_or)
  @taxon_name_classification = params[:taxon_name_classification] || []
  @taxon_name_id = params[:taxon_name_id]
  @taxon_name_relationship = params[:taxon_name_relationship] || []
  @taxon_name_relationship_type = params[:taxon_name_relationship_type] || []
  @taxon_name_type = params[:taxon_name_type]
  @type_metadata = boolean_param(params, :type_metadata)
  @validify = boolean_param(params, :validify)
  @validity = boolean_param(params, :validity)
  @year = params[:year]
  @year_end = params[:year_end]
  @year_start = params[:year_start]

  set_citations_params(params)
  set_depiction_params(params)
  set_notes_params(params)
  set_data_attributes_params(params)
  set_tags_params(params)
end

Instance Attribute Details

#ancestorsObject

Returns Boolean Ignored when taxon_name_id[].empty? Works as AND clause with descendants :(.

Parameters:

  • ancestors (Boolean, 'true', 'false', nil)

Returns:

  • Boolean Ignored when taxon_name_id[].empty? Works as AND clause with descendants :(



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

def ancestors
  @ancestors
end

#ancestrifyObject

!! This parameter is not like the others, it is applied POST result, see also synonymify and validify, etc.

Parameters:

  • ancestrify (Boolean)

    true - extend result to include all ancestors of names in the result along with the result false/nil - ignore



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

def ancestrify
  @ancestrify
end

#authorObject

Parameters:

  • author (String)

    Use “&” for “and”. Matches against cached_author_year. See also author_exact.



112
113
114
# File 'lib/queries/taxon_name/filter.rb', line 112

def author
  @author
end

#author_exactObject

Returns Boolean.

Returns:

  • Boolean



115
116
117
# File 'lib/queries/taxon_name/filter.rb', line 115

def author_exact
  @author_exact
end

#authorsObject

‘true’ or ‘false’

on initialize

whether the name has an author string, from any source, provided

Parameters:

  • authors (Boolean, nil)


224
225
226
# File 'lib/queries/taxon_name/filter.rb', line 224

def authors
  @authors
end

#collecting_event_idObject

Returns Array.

Parameters:

  • collecting_event_id (String, Array)

Returns:

  • Array



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

def collecting_event_id
  @collecting_event_id
end

#collection_object_idObject

Returns Array.

Parameters:

  • collection_object_id (String, Array)

Returns:

  • Array



79
80
81
# File 'lib/queries/taxon_name/filter.rb', line 79

def collection_object_id
  @collection_object_id
end

#combination_taxon_name_idArray

Returns taxon_name_ids for which all Combinations will be returned.

Returns:

  • (Array)

    taxon_name_ids for which all Combinations will be returned



274
275
276
# File 'lib/queries/taxon_name/filter.rb', line 274

def combination_taxon_name_id
  @combination_taxon_name_id
end

#combinationifyObject

!! This parameter is not like the others, it is applied POST result, see also synonymify and validify

Parameters:

  • combinationify (Boolean)

    true - extend result to include all Combinations in which the finest name is a member of the result false/nil - ignore



92
93
94
# File 'lib/queries/taxon_name/filter.rb', line 92

def combinationify
  @combinationify
end

#combinationsObject

This parameter should be used along side species or genus group limits.

Parameters:

  • combinations (Boolean)

    true - only return names that have (subsequent) Combinations false - only return names without (subequent) Combinations nil - ignore



86
87
88
# File 'lib/queries/taxon_name/filter.rb', line 86

def combinations
  @combinations
end

#descendantsBoolean

Returns true - only descendants NOT SELF false - self AND descendants nil - ignored Ignored when taxon_name_id[].empty?.

Parameters:

  • descendants (Boolean, 'true', 'false', nil)

    Read carefully! descendants = false is NOT no descendants, it’s descendants and self

Returns:

  • (Boolean)

    true - only descendants NOT SELF false - self AND descendants nil - ignored Ignored when taxon_name_id[].empty?



168
169
170
# File 'lib/queries/taxon_name/filter.rb', line 168

def descendants
  @descendants
end

#descendants_max_depthInteger?

A positive integer indicating how many levels deep of descendants to retrieve.

Ignored when descentants is false/unspecified.
Defaults to nil

Parameters:

  • descendants_max_depth (Integer)

Returns:

  • (Integer, nil)


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

def descendants_max_depth
  @descendants_max_depth
end

#etymologyObject

‘true’ or ‘false’

on initialize

whether the name has etymology

Parameters:

  • etymology (Boolean, nil)


219
220
221
# File 'lib/queries/taxon_name/filter.rb', line 219

def etymology
  @etymology
end

#geo_jsonObject

Returns the value of attribute geo_json.



283
284
285
# File 'lib/queries/taxon_name/filter.rb', line 283

def geo_json
  @geo_json
end

#leavesBoolean?

TODO: inverse is duplicated in autocomplete

Returns:

  • (Boolean, nil)

    &leaves=<“true”|“false”> if ‘true’ then return only names without descendents if ‘false’ then return only names with descendents



252
253
254
# File 'lib/queries/taxon_name/filter.rb', line 252

def leaves
  @leaves
end

#nameArray

Returns Matches against cached. See also name_exact.

Parameters:

  • name (String, Array)

Returns:

  • (Array)

    Matches against cached. See also name_exact.



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

def name
  @name
end

#name_exactObject

Returns Boolean.

Returns:

  • Boolean



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

def name_exact
  @name_exact
end

#nomenclature_codeString?

Returns accessor for attr :nomenclature_code, wrap with needed wildcards.

Returns:

  • (String, nil)

    accessor for attr :nomenclature_code, wrap with needed wildcards



245
246
247
# File 'lib/queries/taxon_name/filter.rb', line 245

def nomenclature_code
  @nomenclature_code
end

#nomenclature_dateObject

Returns Boolean with/out cached nomenclature date set.

Parameters:

  • ancestors (Boolean, 'true', 'false', nil)

Returns:

  • Boolean with/out cached nomenclature date set



125
126
127
# File 'lib/queries/taxon_name/filter.rb', line 125

def nomenclature_date
  @nomenclature_date
end

#nomenclature_groupString?

Returns accessor for attr :nomenclature_group, wrap with needed wildcards.

Returns:

  • (String, nil)

    accessor for attr :nomenclature_group, wrap with needed wildcards



241
242
243
# File 'lib/queries/taxon_name/filter.rb', line 241

def nomenclature_group
  @nomenclature_group
end

#not_specifiedObject

Returns the value of attribute not_specified.



236
237
238
# File 'lib/queries/taxon_name/filter.rb', line 236

def not_specified
  @not_specified
end

#original_combinationBoolean?

Returns true - name has at least one element of original combination false - name has no element of original combination nil - ignored.

Parameters:

  • original_combination (Boolean)

Returns:

  • (Boolean, nil)

    true - name has at least one element of original combination false - name has no element of original combination nil - ignored



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

def original_combination
  @original_combination
end

#otu_idArray?

Returns one or more OTU ids.

Parameters:

  • otu_id (Array, nil)

Returns:

  • (Array, nil)

    one or more OTU ids



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

def otu_id
  @otu_id
end

#otusObject

‘true’ or ‘false’

on initialize

whether the name has an Otu

Parameters:

  • otus (Boolean, nil)


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

def otus
  @otus
end

#parent_idObject

Return the taxon names with this/these parent_ids

Returns:

  • Return the taxon names with this/these parent_ids



159
160
161
# File 'lib/queries/taxon_name/filter.rb', line 159

def parent_id
  @parent_id
end

#rankArray

Returns:

  • (Array)


281
282
283
# File 'lib/queries/taxon_name/filter.rb', line 281

def rank
  @rank
end

#sortString?

Parameters:

  • sort (String, nil)

    one of :classification, :alphabetical

Returns:

  • (String, nil)


270
271
272
# File 'lib/queries/taxon_name/filter.rb', line 270

def sort
  @sort
end

#synonymifyObject

!! This parameter is not like the others, it is applied POST result, see also combinationify and validify

Parameters:

  • synonymify (Boolean)

    true - extend result to include all Synonyms of any member of the list false/nil - ignore



181
182
183
# File 'lib/queries/taxon_name/filter.rb', line 181

def synonymify
  @synonymify
end

#taxon_name_author_idArray

Returns:

  • (Array)


259
260
261
# File 'lib/queries/taxon_name/filter.rb', line 259

def taxon_name_author_id
  @taxon_name_author_id
end

#taxon_name_author_id_orBoolean

Parameters:

  • `false`, (String)

    nil - treat the ids in taxon_name_author_id as “or” (match any TaxonName with any of these authors) ‘true’ - treat the ids in taxon_name_author_id as “and” (only TaxonNames with all and only all will match)

Returns:

  • (Boolean)


265
266
267
# File 'lib/queries/taxon_name/filter.rb', line 265

def taxon_name_author_id_or
  @taxon_name_author_id_or
end

#taxon_name_classificationObject

Parameters:

  • taxon_name_classification (Array)

    Class names of TaxonNameClassification, as strings.



197
198
199
# File 'lib/queries/taxon_name/filter.rb', line 197

def taxon_name_classification
  @taxon_name_classification
end

#taxon_name_idObject

Return the taxon name(s) with this/these ids

Returns:

  • Return the taxon name(s) with this/these ids



153
154
155
# File 'lib/queries/taxon_name/filter.rb', line 153

def taxon_name_id
  @taxon_name_id
end

#taxon_name_relationshipObject

Each entry must have a ‘type’ Each entry must have one (and only one) of ‘subject_taxon_name_id’ or ‘object_taxon_name_id’

Return all taxon names in a relationship of a given type and in relation to a another name. For example, return all synonyms of Aus bus.

Parameters:

  • taxon_name_relationship (Array)
    { ‘type’ => ‘TaxonNameRelationship::<>’, ‘subject|object_taxon_name_id’ => ‘123’ } … {}


189
190
191
# File 'lib/queries/taxon_name/filter.rb', line 189

def taxon_name_relationship
  @taxon_name_relationship
end

#taxon_name_relationship_typeObject

Parameters:

  • taxon_name_relationship (Array)

    All names involved in any of these relationship



193
194
195
# File 'lib/queries/taxon_name/filter.rb', line 193

def taxon_name_relationship_type
  @taxon_name_relationship_type
end

#taxon_name_typeString?

Returns &taxon_name_type=<Protonym|Combination|Hybrid>.

Returns:

  • (String, nil)

    &taxon_name_type=<Protonym|Combination|Hybrid>



256
257
258
# File 'lib/queries/taxon_name/filter.rb', line 256

def taxon_name_type
  @taxon_name_type
end

#type_metadataObject

‘true’ or ‘false’

on initialize

whether the name has TypeMaterial


229
230
231
# File 'lib/queries/taxon_name/filter.rb', line 229

def 
  @type_metadata
end

#validifyObject

name is returned !! This param is not like the others. !!

Returns:

  • Boolean if true then for each name in the result its valid



147
148
149
# File 'lib/queries/taxon_name/filter.rb', line 147

def validify
  @validify
end

#validityObject

‘true’ or ‘false’

on initialize

true if only valid, false if only invalid, nil if both


140
141
142
# File 'lib/queries/taxon_name/filter.rb', line 140

def validity
  @validity
end

#yearObject

Matches against cached_author_year.

Parameters:

  • year (String)

    “yyyy”



120
121
122
# File 'lib/queries/taxon_name/filter.rb', line 120

def year
  @year
end

#year_endObject

Matches against cached_nomenclature_date

Parameters:

  • year_end (String)

    “yyyy”



135
136
137
# File 'lib/queries/taxon_name/filter.rb', line 135

def year_end
  @year_end
end

#year_startObject

Matches against cached_nomenclature_date

Parameters:

  • year_start (String)

    “yyyy”



130
131
132
# File 'lib/queries/taxon_name/filter.rb', line 130

def year_start
  @year_start
end

Instance Method Details

#all(nil_empty = false) ⇒ ActiveRecord::Relation

Returns:

  • (ActiveRecord::Relation)


903
904
905
906
907
908
909
910
911
912
913
# File 'lib/queries/taxon_name/filter.rb', line 903

def all(nil_empty = false)
  q = super
  q = validify_result(q) if validify
  q = combinationify_result(q) if combinationify
  q = synonimify_result(q) if synonymify
  q = order_clause(q) if sort

  q = ancestrify_result(q) if ancestrify

  q
end

#ancestor_facetObject

A merge facet.

Returns:

  • Scope match only names that are a ancestor of some taxon_name_id



491
492
493
494
495
496
497
498
499
500
501
# File 'lib/queries/taxon_name/filter.rb', line 491

def ancestor_facet
  return nil if taxon_name_id.empty? || !(ancestors == true)

  ancestors_subquery = ::TaxonNameHierarchy.where(
    ::TaxonNameHierarchy.arel_table[:ancestor_id].eq(::TaxonName.arel_table[:id]).and(
      ::TaxonNameHierarchy.arel_table[:descendant_id].in(taxon_name_id)
    )
  )

  ::TaxonName.where(ancestors_subquery.arel.exists)
end

#ancestrify_result(q) ⇒ Object



870
871
872
873
874
875
876
877
878
879
880
881
882
# File 'lib/queries/taxon_name/filter.rb', line 870

def ancestrify_result(q)
  s = 'WITH tn_result_query_anc AS (' + q.to_sql + ') ' +
      ::TaxonName
        .joins('JOIN taxon_name_hierarchies tnh on tnh.ancestor_id = taxon_names.id')
        .joins('JOIN tn_result_query_anc as tn_result_query_anc1 on tn_result_query_anc1.id = tnh.descendant_id')
        .distinct
        .to_sql

  # !! Do not use .distinct here
  a = ::TaxonName.from('(' + s + ') as taxon_names')

  a
end

#and_clausesActiveRecord::Relation

Returns:

  • (ActiveRecord::Relation)


782
783
784
785
786
787
788
789
790
791
792
793
794
795
# File 'lib/queries/taxon_name/filter.rb', line 782

def and_clauses
  [
    nomenclature_date_facet,
    author_facet,
    name_facet,
    parent_id_facet,
    rank_facet,
    taxon_name_type_facet,
    validity_facet,
    with_nomenclature_code,
    with_nomenclature_group,
    year_facet,
  ]
end

#asserted_distribution_query_facetObject



731
732
733
734
735
736
737
738
739
740
# File 'lib/queries/taxon_name/filter.rb', line 731

def asserted_distribution_query_facet
  return nil if asserted_distribution_query.nil?
  s = 'WITH query_ad_tn AS (' + asserted_distribution_query.all.to_sql + ') ' +
      ::TaxonName
        .joins(otus: [:asserted_distributions])
        .joins('JOIN query_ad_tn as query_ad_tn1 on query_ad_tn1.otu_id = asserted_distributions.otu_id')
        .to_sql

  ::TaxonName.from('(' + s + ') as taxon_names').distinct
end

#author_facetObject



660
661
662
663
664
665
666
667
# File 'lib/queries/taxon_name/filter.rb', line 660

def author_facet
  return nil if author.blank?
  if author_exact
    table[:cached_author_year].eq(author.strip)
  else
    table[:cached_author_year].matches('%' + author.strip.gsub(/\s/, '%') + '%')
  end
end

#authors_facetObject

This is not true! It includes records that are year only.

Returns:

  • Scope



521
522
523
524
525
526
# File 'lib/queries/taxon_name/filter.rb', line 521

def authors_facet
  return nil if authors.nil?
  authors ?
    ::TaxonName.where.not(cached_author_year: nil) :
    ::TaxonName.where(cached_author_year: nil)
end

#biological_association_query_facetObject



764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
# File 'lib/queries/taxon_name/filter.rb', line 764

def biological_association_query_facet
  return nil if biological_association_query.nil?
  s = 'WITH query_tn_ba AS (' + biological_association_query.all.to_sql + ') '

  a = ::TaxonName
    .joins(:otus)
    .joins("JOIN query_tn_ba as query_tn_ba1 on query_tn_ba1.biological_association_subject_id = otus.id AND query_tn_ba1.biological_association_subject_type = 'Otu'").to_sql

  b = ::TaxonName
    .joins(:otus)
    .joins("JOIN query_tn_ba as query_tn_ba2 on query_tn_ba2.biological_association_object_id = otus.id AND query_tn_ba2.biological_association_object_type = 'Otu'").to_sql

  s << ::TaxonName.from("((#{a}) UNION (#{b})) as taxon_names").to_sql

  ::TaxonName.from('(' + s + ') as taxon_names')
end

#collecting_event_id_facetObject



703
704
705
706
707
708
# File 'lib/queries/taxon_name/filter.rb', line 703

def collecting_event_id_facet
  return nil if collecting_event_id.empty?
  ::TaxonName
    .joins(:collection_objects)
    .where(collection_objects: { collecting_event_id: })
end

#collecting_event_query_facetObject



753
754
755
756
757
758
759
760
761
762
# File 'lib/queries/taxon_name/filter.rb', line 753

def collecting_event_query_facet
  return nil if collecting_event_query.nil?
  s = 'WITH query_ce_tns AS (' + collecting_event_query.all.to_sql + ') ' +
      ::TaxonName
        .joins(:collection_objects)
        .joins('JOIN query_ce_tns as query_ce_tns1 on collection_objects.collecting_event_id = query_ce_tns1.id')
        .to_sql

  ::TaxonName.from('(' + s + ') as taxon_names').distinct
end

#collection_object_id_facetObject



503
504
505
506
# File 'lib/queries/taxon_name/filter.rb', line 503

def collection_object_id_facet
  return nil if collection_object_id.empty?
  ::TaxonName.joins(:collection_objects).where(collection_objects: { id: collection_object_id })
end

#collection_object_query_facetObject



742
743
744
745
746
747
748
749
750
751
# File 'lib/queries/taxon_name/filter.rb', line 742

def collection_object_query_facet
  return nil if collection_object_query.nil?
  s = 'WITH query_collection_objects AS (' + collection_object_query.all.to_sql + ') ' +
      ::TaxonName
        .joins(:collection_objects)
        .joins('JOIN query_collection_objects as query_collection_objects1 on collection_objects.id = query_collection_objects1.id')
        .to_sql

  ::TaxonName.from('(' + s + ') as taxon_names').distinct
end

#combination_taxon_name_id_facetObject



692
693
694
695
696
697
698
699
700
701
# File 'lib/queries/taxon_name/filter.rb', line 692

def combination_taxon_name_id_facet
  return nil if combination_taxon_name_id.empty?
  ::Combination.joins(:related_taxon_name_relationships)
    .where(
      taxon_name_relationships: {
        type: ::TAXON_NAME_RELATIONSHIP_COMBINATION_TYPES.values,
        subject_taxon_name_id: combination_taxon_name_id,
      },
    ).distinct
end

#combinationify_result(q) ⇒ Object



858
859
860
861
862
863
864
865
866
867
868
# File 'lib/queries/taxon_name/filter.rb', line 858

def combinationify_result(q)
  s = 'WITH tn_result_query AS (' + q.to_sql + ') ' +
      ::TaxonName
        .joins('JOIN tn_result_query as tn_result_query3 on tn_result_query3.id = taxon_names.cached_valid_taxon_name_id')
        .where("taxon_names.type = 'Combination'")
        .to_sql

  a = ::TaxonName.from('(' + s + ') as taxon_names').distinct

  referenced_klass_union([q, a])
end

#combinations_facetObject



710
711
712
713
714
715
716
717
718
# File 'lib/queries/taxon_name/filter.rb', line 710

def combinations_facet
  return nil if combinations.nil?
  a = ::Protonym.joins(:combination_relationships)
  if combinations
    a
  else
    referenced_klass_except(a)
  end
end

#descendant_facetObject

Returns Scope match only names that are a descendant of some taxon_name_id.

Returns:

  • Scope match only names that are a descendant of some taxon_name_id



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
# File 'lib/queries/taxon_name/filter.rb', line 461

def descendant_facet
  return nil if taxon_name_id.empty? || descendants.nil?

  h = ::TaxonNameHierarchy.arel_table

  if descendants
    descendants_subquery = ::TaxonNameHierarchy.where(
      h[:descendant_id].eq(::TaxonName.arel_table[:id]).and(
        h[:ancestor_id].in(taxon_name_id)
      )
    ).where(h[:ancestor_id].not_eq(h[:descendant_id]))

    if descendants_max_depth.present?
      descendants_subquery = descendants_subquery.where(::TaxonNameHierarchy.arel_table[:generations].lteq(descendants_max_depth.to_i))
    end

    ::TaxonName.where(descendants_subquery.arel.exists)
  else
    q = ::TaxonName.joins('JOIN taxon_name_hierarchies ON taxon_name_hierarchies.descendant_id = taxon_names.id')
      .where(taxon_name_hierarchies: {ancestor_id: taxon_name_id})
     if descendants_max_depth.present?
       q = q.where(::TaxonNameHierarchy.arel_table[:generations].lteq(descendants_max_depth.to_i))
     end
     q
  end
end

#geo_json_facetObject



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

def geo_json_facet
  return nil if geo_json.nil?
  otus = ::Queries::Otu::Filter.new(geo_json:).all
  collection_objects = ::Queries::CollectionObject::Filter.new(geo_json:).all

  a = ::TaxonName.joins(:taxon_taxon_determinations).where(taxon_determinations: { biological_collection_object: collection_objects })
  b = ::TaxonName.joins(:otus).where(otus:)

  ::TaxonName.from("((#{a.to_sql}) UNION (#{b.to_sql})) as taxon_names")
end

#leaves_facetObject

Returns Scope.

Returns:

  • Scope



543
544
545
546
# File 'lib/queries/taxon_name/filter.rb', line 543

def leaves_facet
  return nil if leaves.nil?
  leaves ? ::TaxonName.leaves : ::TaxonName.not_leaves
end

#merge_clausesObject



797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
# File 'lib/queries/taxon_name/filter.rb', line 797

def merge_clauses
  clauses = [
    asserted_distribution_query_facet,
    biological_association_query_facet,
    collecting_event_query_facet,
    collection_object_query_facet,
    otu_query_facet,

    ancestor_facet,
    authors_facet,
    collecting_event_id_facet,
    collection_object_id_facet,
    combination_taxon_name_id_facet,
    combinations_facet,
    descendant_facet,
    leaves_facet,
    not_specified_facet,
    original_combination_facet,
    otu_id_facet,
    taxon_name_author_id_facet,
    otus_facet,
    taxon_name_classification_facet,
    taxon_name_relationship_type_facet,
    ,
    with_etymology_facet,
    year_range_facet,
  ]

  taxon_name_relationship.each do |hsh|
    clauses << taxon_name_relationship_facet(hsh)
  end

  clauses.compact
end

#model_id_facetObject

Overrides base class



833
834
835
836
# File 'lib/queries/taxon_name/filter.rb', line 833

def model_id_facet
  return nil if taxon_name_id.empty? || !descendants.nil? || ancestors
  table[:id].in(taxon_name_id)
end

#name_facetObject



645
646
647
648
649
650
651
652
653
# File 'lib/queries/taxon_name/filter.rb', line 645

def name_facet
  return nil if name.empty?
  if name_exact
    table[:cached].in(name).or(table[:cached_original_combination].in(name))
    #  table[:cached].eq(name.strip).or(table[:cached_original_combination].eq(name.strip))
  else
    table[:cached].matches_any(name.collect { |n| '%' + n.gsub(/\s+/, '%') + '%' }).or(table[:cached_original_combination].matches_any(name.collect { |n| '%' + n.gsub(/\s+/, '%') + '%' }))
  end
end

#nomenclature_date_facetObject



450
451
452
453
454
455
456
457
# File 'lib/queries/taxon_name/filter.rb', line 450

def nomenclature_date_facet
  return nil if nomenclature_date.nil?
  if nomenclature_date
    table[:cached_nomenclature_date].not_eq(nil)
  else
    table[:cached_nomenclature_date].eq(nil)
  end
end

#not_specified_facetObject



428
429
430
431
432
433
434
435
436
437
438
439
# File 'lib/queries/taxon_name/filter.rb', line 428

def not_specified_facet
  return nil if not_specified.nil?
  if not_specified
    ::TaxonName.where(table[:cached].matches('%NOT SPECIFIED%').or(
      table[:cached_original_combination].matches('%NOT SPECIFIED%')
    ))
  else
    ::TaxonName.where(table[:cached].does_not_match('%NOT SPECIFIED%').and(
      table[:cached_original_combination].does_not_match('%NOT SPECIFIED%')
    ))
  end
end

#order_clause(query) ⇒ Object



884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
# File 'lib/queries/taxon_name/filter.rb', line 884

def order_clause(query)
  case sort
  when 'alphabetical'
    ::TaxonName.select('*').from(
      query.order('taxon_names.cached'), :inner_query
    )
  when 'classification'
    ::TaxonName.select('*').from(
      query
        .joins('INNER JOIN taxon_name_hierarchies ON taxon_names.id = taxon_name_hierarchies.descendant_id')
        .order('taxon_name_hierarchies.generations, taxon_name_hierarchies.ancestor_id, taxon_names.cached'),
      :inner_query
    )
  else
    query
  end
end

#original_combination_facetObject



441
442
443
444
445
446
447
448
# File 'lib/queries/taxon_name/filter.rb', line 441

def original_combination_facet
  return nil if original_combination.nil?
  if original_combination
    ::Protonym.joins(:original_combination_relationships)
  else
    ::Protonym.where.missing(:original_combination_relationships)
  end
end

#otu_id_facetObject



508
509
510
511
# File 'lib/queries/taxon_name/filter.rb', line 508

def otu_id_facet
  return nil if otu_id.empty?
  ::TaxonName.joins(:otus).where(otus: { id: otu_id })
end

#otu_query_facetObject



720
721
722
723
724
725
726
727
728
729
# File 'lib/queries/taxon_name/filter.rb', line 720

def otu_query_facet
  return nil if otu_query.nil?
  s = 'WITH query_otu_tn AS (' + otu_query.all.to_sql + ') ' +
      ::TaxonName
        .joins(:otus)
        .joins('JOIN query_otu_tn as query_otu_tn1 on otus.id = query_otu_tn1.id') # Don't change, see `validify`
        .to_sql

  ::TaxonName.from('(' + s + ') as taxon_names').distinct
end

#otus_facetObject

Returns Scope.

Returns:

  • Scope



614
615
616
617
618
# File 'lib/queries/taxon_name/filter.rb', line 614

def otus_facet
  return nil if otus.nil?
  subquery = ::Otu.where(::Otu.arel_table[:taxon_name_id].eq(::TaxonName.arel_table[:id])).arel.exists
  ::TaxonName.where(otus ? subquery : subquery.not)
end

#parent_id_facetObject



655
656
657
658
# File 'lib/queries/taxon_name/filter.rb', line 655

def parent_id_facet
  return nil if parent_id.empty?
  table[:parent_id].in(parent_id)
end

#rank_facetArel::Nodes::Grouping?

Returns:

  • (Arel::Nodes::Grouping, nil)


627
628
629
630
631
632
# File 'lib/queries/taxon_name/filter.rb', line 627

def rank_facet
  return nil if rank.blank?
  # We don't wildcard end so that we can isolate to specific ranks and below
  r = rank.collect { |i| "%#{i}" }
  table[:rank_class].matches_any(r)
end

#synonimify_result(q) ⇒ Object



847
848
849
850
851
852
853
854
855
856
# File 'lib/queries/taxon_name/filter.rb', line 847

def synonimify_result(q)
  s = 'WITH tn_result_query AS (' + q.to_sql + ') ' +
      ::TaxonName
        .joins('JOIN tn_result_query as tn_result_query2 on tn_result_query2.id = taxon_names.cached_valid_taxon_name_id')
        .to_sql

  a = ::TaxonName.from('(' + s + ') as taxon_names').distinct

  referenced_klass_union([q, a])
end

#taxon_name_author_id_facetObject



578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
# File 'lib/queries/taxon_name/filter.rb', line 578

def taxon_name_author_id_facet
  return nil if taxon_name_author_id.empty?
  o = table
  r = ::Role.arel_table

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

  c = r.alias('r1')

  b = b.join(c, Arel::Nodes::OuterJoin)
    .on(
      a[:id].eq(c[:role_object_id])
        .and(c[:role_object_type].eq('TaxonName'))
        .and(c[:type].eq('TaxonNameAuthor'))
    )

  e = c[:id].not_eq(nil)
  f = c[:person_id].in(taxon_name_author_id)

  b = b.where(e.and(f))
  b = b.group(a['id'])
  b = b.having(a['id'].count.eq(taxon_name_author_id.length)) unless taxon_name_author_id_or
  b = b.as('tn_z1_')

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

#taxon_name_classification_facetObject

Returns Scope.

Returns:

  • Scope



566
567
568
569
570
571
572
573
574
575
576
# File 'lib/queries/taxon_name/filter.rb', line 566

def taxon_name_classification_facet
  return nil if taxon_name_classification.empty?

  ::TaxonName.where(
    ::TaxonNameClassification.where(
      ::TaxonNameClassification.arel_table[:taxon_name_id].eq(::TaxonName.arel_table[:id]).and(
        ::TaxonNameClassification.arel_table[:type].in(taxon_name_classification)
      )
    ).arel.exists
  )
end

#taxon_name_relationship_facet(hsh) ⇒ Object

Returns Scope wrapped in descendant_facet!.

Returns:

  • Scope wrapped in descendant_facet!



550
551
552
553
554
555
556
557
558
559
560
561
562
563
# File 'lib/queries/taxon_name/filter.rb', line 550

def taxon_name_relationship_facet(hsh)
  param_key = hsh['subject_taxon_name_id'] ? 'subject_taxon_name_id' : 'object_taxon_name_id'
  join_key = hsh['subject_taxon_name_id'] ? 'object_taxon_name_id' : 'subject_taxon_name_id'

  ::TaxonName.where(
    ::TaxonNameRelationship.where(
      ::TaxonNameRelationship.arel_table[join_key].eq(::TaxonName.arel_table[:id]).and(
        ::TaxonNameRelationship.arel_table[param_key].eq(hsh[param_key])
      ).and(
        ::TaxonNameRelationship.arel_table[:type].eq(hsh['type'])
      )
    ).arel.exists
  )
end

#taxon_name_relationship_type_facetObject

Returns Scope.

Returns:

  • Scope



537
538
539
540
# File 'lib/queries/taxon_name/filter.rb', line 537

def taxon_name_relationship_type_facet
  return nil if taxon_name_relationship_type.empty?
  ::TaxonName.with_taxon_name_relationship(taxon_name_relationship_type)
end

#taxon_name_type_facetObject



640
641
642
643
# File 'lib/queries/taxon_name/filter.rb', line 640

def taxon_name_type_facet
  return nil if taxon_name_type.blank?
  table[:type].eq(taxon_name_type)
end

#type_metadata_facetObject

Returns Scope.

Returns:

  • Scope



607
608
609
610
611
# File 'lib/queries/taxon_name/filter.rb', line 607

def 
  return nil if .nil?
  subquery = ::TypeMaterial.where(::TypeMaterial.arel_table[:protonym_id].eq(::TaxonName.arel_table[:id])).arel.exists
  ::TaxonName.where( ? subquery : subquery.not)
end

#validify_result(q) ⇒ Object



838
839
840
841
842
843
844
845
# File 'lib/queries/taxon_name/filter.rb', line 838

def validify_result(q)
  s = 'WITH tn_result_query AS (' + q.to_sql + ') ' +
      ::TaxonName
        .joins('JOIN tn_result_query as tn_result_query1 on tn_result_query1.cached_valid_taxon_name_id = taxon_names.id')
        .to_sql

  ::TaxonName.from('(' + s + ') as taxon_names').distinct
end

#validity_facetObject



683
684
685
686
687
688
689
690
# File 'lib/queries/taxon_name/filter.rb', line 683

def validity_facet
  return nil if validity.nil?
  if validity
    table[:cached_is_valid].eq(true)
  else
    table[:cached_is_valid].eq(false)
  end
end

#with_etymology_facetObject

Returns Scope.

Returns:

  • Scope



529
530
531
532
533
534
# File 'lib/queries/taxon_name/filter.rb', line 529

def with_etymology_facet
  return nil if etymology.nil?
  etymology ?
    ::TaxonName.where.not(etymology: nil) :
    ::TaxonName.where(etymology: nil)
end

#with_nomenclature_codeArel::Nodes::Grouping?

Returns:

  • (Arel::Nodes::Grouping, nil)


635
636
637
638
# File 'lib/queries/taxon_name/filter.rb', line 635

def with_nomenclature_code
  return nil if nomenclature_code.nil?
  table[:rank_class].matches(nomenclature_code)
end

#with_nomenclature_groupArel::Nodes::Grouping?

Returns:

  • (Arel::Nodes::Grouping, nil)


621
622
623
624
# File 'lib/queries/taxon_name/filter.rb', line 621

def with_nomenclature_group
  return nil if nomenclature_group.blank?
  table[:rank_class].matches(nomenclature_group)
end

#year_facetObject



669
670
671
672
673
674
675
# File 'lib/queries/taxon_name/filter.rb', line 669

def year_facet
  return nil if year.blank?

  s = Date.new(@year.to_i)
  e = Date.new(@year.to_i, 12, 31)
  table[:cached_nomenclature_date].between(s..e)
end

#year_range_facetObject



677
678
679
680
681
# File 'lib/queries/taxon_name/filter.rb', line 677

def year_range_facet
  return nil if year_end.nil? && year_start.nil?
  s, e = [year_start, year_end].compact
  ::TaxonName.where(cached_nomenclature_date: (s..e))
end