Class: Queries::TaxonName::Filter
- Includes:
- Concerns::Tags, Concerns::Users
- Defined in:
- lib/queries/taxon_name/filter.rb
Overview
Instance Attribute Summary collapse
-
#ancestors ⇒ Object
- 'true' or 'false'
-
on initialize Ignored when taxon_name_id[].empty? Works as AND clause with descendants :(.
- #author ⇒ Object
-
#authors ⇒ Object
- 'true' or 'false'
-
on initialize whether the name has an author string, from any source, provided.
-
#citations ⇒ Object
Returns the value of attribute citations.
-
#descendants ⇒ Object
- 'true' or 'false'
-
on initialize Ignored when taxon_name_id[].empty? Return descendants of parents as well.
-
#descendants_max_depth ⇒ Object
A positive integer indicating how many levels deep of descenants to retrieve.
-
#etymology ⇒ Object
- 'true' or 'false'
-
on initialize whether the name has etymology.
- #exact ⇒ Object
-
#leaves ⇒ Boolean?
TODO: inverse is duplicated in autocomplete.
- #name ⇒ Object
-
#nomenclature_code ⇒ String?
Accessor for attr :nomenclature_code, wrap with needed wildcards.
-
#nomenclature_group ⇒ String?
Accessor for attr :nomenclature_group, wrap with needed wildcards.
-
#otus ⇒ Object
- 'true' or 'false'
-
on initialize whether the name has an Otu.
-
#parent_id ⇒ Object
Return the taxon names with this/these parent_ids.
-
#project_id ⇒ Object
TODO: probably should be an array for API purposes.
- #sort ⇒ String?
- #taxon_name_author_ids ⇒ Array
- #taxon_name_author_ids_or ⇒ Boolean
- #taxon_name_classification ⇒ Object
-
#taxon_name_id ⇒ Object
Return the taxon name(s) with this/these ids.
-
#taxon_name_relationship ⇒ Object
Each entry must have a 'type' Each entry must have one (and only one) of 'subject_taxon_name_id' or 'object_taxon_name_id'.
- #taxon_name_relationship_type ⇒ Object
-
#taxon_name_type ⇒ String?
&taxon_name_type=<Protonym|Combination|Hybrid>.
-
#type_metadata ⇒ Object
- 'true' or 'false'
-
on initialize whether the name has TypeMaterial.
-
#updated_since ⇒ Object
TODO: deprecate for Queries::Concerns::User.
-
#validity ⇒ Object
- 'true' or 'false'
-
on initialize true if only valid, false if only invalid, nil if both.
-
#year ⇒ Object
Matches against cached_author_year.
Attributes inherited from Query
#dynamic_limit, #options, #query_string, #terms
Instance Method Summary collapse
- #all ⇒ ActiveRecord::Relation
-
#ancestor_facet ⇒ Object
A merge facet.
- #and_clauses ⇒ ActiveRecord::Relation
- #author_facet ⇒ Object
-
#authors_facet ⇒ Object
Scope.
- #base_query ⇒ Object
- #cached_name ⇒ Object
-
#citations_facet ⇒ Object
Scope.
-
#descendant_facet ⇒ Object
A merge facet.
-
#initialize(params) ⇒ Filter
constructor
A new instance of Filter.
-
#leaves_facet ⇒ Object
Scope.
-
#matching_taxon_name_author_ids ⇒ Object
TODO: dry with Source, CollectingEvent , etc.
- #merge_clauses ⇒ Object
- #order_clause(query) ⇒ Object
-
#otus_facet ⇒ Object
Scope.
- #parent_id_facet ⇒ Object
- #table ⇒ Arel::Table
-
#taxon_name_classification_facet ⇒ Object
Scope.
- #taxon_name_id_facet ⇒ Object
-
#taxon_name_relationship_facet(hsh) ⇒ Object
Scope wrapped in descendant_facet!.
-
#taxon_name_relationship_type_facet ⇒ Object
Scope.
- #taxon_name_type_facet ⇒ Object
-
#type_metadata_facet ⇒ Object
Scope.
- #updated_since_facet ⇒ Object
- #validity_facet ⇒ Object
-
#with_etymology_facet ⇒ Object
Scope.
-
#with_nomenclature_code ⇒ Arel::Nodes::Grouping?
And clause.
-
#with_nomenclature_group ⇒ Arel::Nodes::Grouping?
And clause.
- #year_facet ⇒ Object
Methods inherited from 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, #levenshtein_distance, #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, #result, #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.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/queries/taxon_name/filter.rb', line 148 def initialize(params) @author = params[:author] @authors = (params[:authors]&.downcase == 'true' ? true : false) if !params[:authors].nil? @citations = params[:citations] @descendants = (params[:descendants]&.downcase == 'true' ? true : false) if !params[:descendants].nil? @descendants_max_depth = params[:descendants_max_depth] @ancestors = (params[:ancestors]&.downcase == 'true' ? true : false) if !params[:ancestors].nil? @exact = (params[:exact]&.downcase == 'true' ? true : false) if !params[:exact].nil? @leaves = (params[:leaves]&.downcase == 'true' ? true : false) if !params[:leaves].nil? @name = params[:name] @nomenclature_code = params[:nomenclature_code] if !params[:nomenclature_code].nil? @nomenclature_group = params[:nomenclature_group] if !params[:nomenclature_group].nil? @otus = (params[:otus]&.downcase == 'true' ? true : false) if !params[:otus].nil? @etymology = (params[:etymology]&.downcase == 'true' ? true : false) if !params[:etymology].nil? @project_id = params[:project_id] @taxon_name_classification = params[:taxon_name_classification] || [] @taxon_name_id = params[:taxon_name_id] || [] @parent_id = params[:parent_id] || [] @sort = params[:sort] @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 = (params[:type_metadata]&.downcase == 'true' ? true : false) if !params[:type_metadata].nil? @updated_since = params[:updated_since].to_s @validity = (params[:validity]&.downcase == 'true' ? true : false) if !params[:validity].nil? @year = params[:year].to_s @taxon_name_author_ids = params[:taxon_name_author_ids].blank? ? [] : params[:taxon_name_author_ids] @taxon_name_author_ids_or = (params[:taxon_name_author_ids_or]&.downcase == 'true' ? true : false) if !params[:taxon_name_author_ids_or].nil? (params) set_user_dates(params) end |
Instance Attribute Details
#ancestors ⇒ Object
- 'true' or 'false'
-
on initialize
Ignored when taxon_name_id[].empty? Works as AND clause with descendants :(
64 65 66 |
# File 'lib/queries/taxon_name/filter.rb', line 64 def ancestors @ancestors end |
#author ⇒ Object
16 17 18 |
# File 'lib/queries/taxon_name/filter.rb', line 16 def @author end |
#authors ⇒ Object
- 'true' or 'false'
-
on initialize
whether the name has an author string, from any source, provided
106 107 108 |
# File 'lib/queries/taxon_name/filter.rb', line 106 def @authors end |
#citations ⇒ Object
Returns the value of attribute citations.
91 92 93 |
# File 'lib/queries/taxon_name/filter.rb', line 91 def citations @citations end |
#descendants ⇒ Object
- 'true' or 'false'
-
on initialize
Ignored when taxon_name_id[].empty? Return descendants of parents as well.
54 55 56 |
# File 'lib/queries/taxon_name/filter.rb', line 54 def descendants @descendants end |
#descendants_max_depth ⇒ Object
A positive integer indicating how many levels deep of descenants to retrieve.
Ignored when descentants is false/unspecified
59 60 61 |
# File 'lib/queries/taxon_name/filter.rb', line 59 def descendants_max_depth @descendants_max_depth end |
#etymology ⇒ Object
101 102 103 |
# File 'lib/queries/taxon_name/filter.rb', line 101 def etymology @etymology end |
#exact ⇒ Object
25 26 27 |
# File 'lib/queries/taxon_name/filter.rb', line 25 def exact @exact end |
#leaves ⇒ Boolean?
TODO: inverse is duplicated in autocomplete
127 128 129 |
# File 'lib/queries/taxon_name/filter.rb', line 127 def leaves @leaves end |
#nomenclature_code ⇒ String?
Returns accessor for attr :nomenclature_code, wrap with needed wildcards.
120 121 122 |
# File 'lib/queries/taxon_name/filter.rb', line 120 def nomenclature_code @nomenclature_code end |
#nomenclature_group ⇒ String?
Returns accessor for attr :nomenclature_group, wrap with needed wildcards.
116 117 118 |
# File 'lib/queries/taxon_name/filter.rb', line 116 def nomenclature_group @nomenclature_group end |
#otus ⇒ Object
96 97 98 |
# File 'lib/queries/taxon_name/filter.rb', line 96 def otus @otus end |
#parent_id ⇒ Object
Return the taxon names with this/these parent_ids
49 50 51 |
# File 'lib/queries/taxon_name/filter.rb', line 49 def parent_id @parent_id end |
#project_id ⇒ Object
TODO: probably should be an array for API purposes. TODO: unify globally as to whether param belongs here, or at controller level.
86 87 88 |
# File 'lib/queries/taxon_name/filter.rb', line 86 def project_id @project_id end |
#sort ⇒ String?
144 145 146 |
# File 'lib/queries/taxon_name/filter.rb', line 144 def sort @sort end |
#taxon_name_author_ids ⇒ Array
134 135 136 |
# File 'lib/queries/taxon_name/filter.rb', line 134 def @taxon_name_author_ids end |
#taxon_name_author_ids_or ⇒ Boolean
139 140 141 |
# File 'lib/queries/taxon_name/filter.rb', line 139 def @taxon_name_author_ids_or end |
#taxon_name_classification ⇒ Object
80 81 82 |
# File 'lib/queries/taxon_name/filter.rb', line 80 def taxon_name_classification @taxon_name_classification end |
#taxon_name_id ⇒ Object
Return the taxon name(s) with this/these ids
43 44 45 |
# File 'lib/queries/taxon_name/filter.rb', line 43 def taxon_name_id @taxon_name_id end |
#taxon_name_relationship ⇒ Object
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.
72 73 74 |
# File 'lib/queries/taxon_name/filter.rb', line 72 def taxon_name_relationship @taxon_name_relationship end |
#taxon_name_relationship_type ⇒ Object
76 77 78 |
# File 'lib/queries/taxon_name/filter.rb', line 76 def taxon_name_relationship_type @taxon_name_relationship_type end |
#taxon_name_type ⇒ String?
Returns &taxon_name_type=<Protonym|Combination|Hybrid>.
131 132 133 |
# File 'lib/queries/taxon_name/filter.rb', line 131 def taxon_name_type @taxon_name_type end |
#type_metadata ⇒ Object
- 'true' or 'false'
-
on initialize
whether the name has TypeMaterial
111 112 113 |
# File 'lib/queries/taxon_name/filter.rb', line 111 def @type_metadata end |
#updated_since ⇒ Object
TODO: deprecate for Queries::Concerns::User
32 33 34 |
# File 'lib/queries/taxon_name/filter.rb', line 32 def updated_since @updated_since end |
#validity ⇒ Object
- 'true' or 'false'
-
on initialize
true if only valid, false if only invalid, nil if both
37 38 39 |
# File 'lib/queries/taxon_name/filter.rb', line 37 def validity @validity end |
#year ⇒ Object
Matches against cached_author_year.
21 22 23 |
# File 'lib/queries/taxon_name/filter.rb', line 21 def year @year end |
Instance Method Details
#all ⇒ ActiveRecord::Relation
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
# File 'lib/queries/taxon_name/filter.rb', line 485 def all a = and_clauses b = merge_clauses q = nil if a && b q = b.where(a) elsif a q = ::TaxonName.where(a) elsif b q = b else q = ::TaxonName.all end q = q.where(project_id: project_id) if project_id q = order_clause(q) if sort q end |
#ancestor_facet ⇒ Object
A merge facet.
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/queries/taxon_name/filter.rb', line 230 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 |
#and_clauses ⇒ ActiveRecord::Relation
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/queries/taxon_name/filter.rb', line 429 def and_clauses clauses = [] clauses += [ parent_id_facet, , cached_name, year_facet, updated_since_facet, validity_facet, taxon_name_id_facet, with_nomenclature_group, with_nomenclature_code, taxon_name_type_facet ].compact return nil if clauses.empty? a = clauses.shift clauses.each do |b| a = a.and(b) end a end |
#author_facet ⇒ Object
395 396 397 398 399 400 401 402 |
# File 'lib/queries/taxon_name/filter.rb', line 395 def return nil if .blank? if exact table[:cached_author_year].eq(.strip) else table[:cached_author_year].matches('%' + .strip.gsub(/\s/, '%') + '%') end end |
#authors_facet ⇒ Object
Returns Scope.
249 250 251 252 253 254 |
# File 'lib/queries/taxon_name/filter.rb', line 249 def return nil if .nil? ? ::TaxonName.where.not(cached_author_year: nil) : ::TaxonName.where(cached_author_year: nil) end |
#base_query ⇒ Object
187 188 189 |
# File 'lib/queries/taxon_name/filter.rb', line 187 def base_query ::TaxonName.select('taxon_names.*') end |
#cached_name ⇒ Object
381 382 383 384 385 386 387 388 |
# File 'lib/queries/taxon_name/filter.rb', line 381 def cached_name return nil if name.blank? if exact table[:cached].eq(name.strip) else table[:cached].matches('%' + name.strip.gsub(/\s+/, '%') + '%') end end |
#citations_facet ⇒ Object
Returns Scope.
349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/queries/taxon_name/filter.rb', line 349 def citations_facet return nil if citations.nil? citation_conditions = ::Citation.arel_table[:citation_object_id].eq(::TaxonName.arel_table[:id]).and( ::Citation.arel_table[:citation_object_type].eq('TaxonName')) if citations == 'without_origin_citation' citation_conditions = citation_conditions.and(::Citation.arel_table[:is_original].eq(true)) end ::TaxonName.where.not(::Citation.where(citation_conditions).arel.exists) end |
#descendant_facet ⇒ Object
A merge facet.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/queries/taxon_name/filter.rb', line 212 def descendant_facet return nil if taxon_name_id.empty? || !(descendants == true) descendants_subquery = ::TaxonNameHierarchy.where( ::TaxonNameHierarchy.arel_table[:descendant_id].eq(::TaxonName.arel_table[:id]).and( ::TaxonNameHierarchy.arel_table[:ancestor_id].in(taxon_name_id)) ) unless descendants_max_depth.nil? || descendants_max_depth.to_i < 0 descendants_subquery = descendants_subquery.where(TaxonNameHierarchy.arel_table[:generations].lteq(descendants_max_depth.to_i)) end ::TaxonName.where(descendants_subquery.arel.exists) end |
#leaves_facet ⇒ Object
Returns Scope.
271 272 273 274 |
# File 'lib/queries/taxon_name/filter.rb', line 271 def leaves_facet return nil if leaves.nil? leaves ? ::TaxonName.leaves : ::TaxonName.not_leaves end |
#matching_taxon_name_author_ids ⇒ Object
TODO: dry with Source, CollectingEvent , etc.
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 |
# File 'lib/queries/taxon_name/filter.rb', line 305 def return nil if .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].eq_any() b = b.where(e.and(f)) b = b.group(a['id']) b = b.having(a['id'].count.eq(.length)) unless b = b.as('tn_z1_') ::TaxonName.joins(Arel::Nodes::InnerJoin.new(b, Arel::Nodes::On.new(b['id'].eq(o['id'])))) end |
#merge_clauses ⇒ Object
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 |
# File 'lib/queries/taxon_name/filter.rb', line 454 def merge_clauses clauses = [ taxon_name_relationship_type_facet, leaves_facet, descendant_facet, ancestor_facet, created_updated_facet, taxon_name_classification_facet, keyword_id_facet, , , otus_facet, , with_etymology_facet, citations_facet ].compact taxon_name_relationship.each do |hsh| clauses << taxon_name_relationship_facet(hsh) end return nil if clauses.empty? a = clauses.shift clauses.each do |b| a = a.merge(b) end a end |
#order_clause(query) ⇒ Object
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
# File 'lib/queries/taxon_name/filter.rb', line 506 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 |
#otus_facet ⇒ Object
Returns Scope.
242 243 244 245 246 |
# File 'lib/queries/taxon_name/filter.rb', line 242 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_facet ⇒ Object
390 391 392 393 |
# File 'lib/queries/taxon_name/filter.rb', line 390 def parent_id_facet return nil if parent_id.empty? table[:parent_id].eq_any(parent_id) end |
#table ⇒ Arel::Table
183 184 185 |
# File 'lib/queries/taxon_name/filter.rb', line 183 def table ::TaxonName.arel_table end |
#taxon_name_classification_facet ⇒ Object
Returns Scope.
292 293 294 295 296 297 298 299 300 301 |
# File 'lib/queries/taxon_name/filter.rb', line 292 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_id_facet ⇒ Object
423 424 425 426 |
# File 'lib/queries/taxon_name/filter.rb', line 423 def taxon_name_id_facet return nil if taxon_name_id.empty? || descendants || ancestors table[:id].eq_any(taxon_name_id) end |
#taxon_name_relationship_facet(hsh) ⇒ Object
Returns Scope wrapped in descendant_facet!.
278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/queries/taxon_name/filter.rb', line 278 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_facet ⇒ Object
Returns Scope.
265 266 267 268 |
# File 'lib/queries/taxon_name/filter.rb', line 265 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_facet ⇒ Object
376 377 378 379 |
# File 'lib/queries/taxon_name/filter.rb', line 376 def taxon_name_type_facet return nil if taxon_name_type.blank? table[:type].eq(taxon_name_type) end |
#type_metadata_facet ⇒ Object
Returns Scope.
335 336 337 338 339 |
# File 'lib/queries/taxon_name/filter.rb', line 335 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 |
#updated_since_facet ⇒ Object
409 410 411 412 |
# File 'lib/queries/taxon_name/filter.rb', line 409 def updated_since_facet return nil if updated_since.blank? table[:updated_at].gt(Date.parse(updated_since)) end |
#validity_facet ⇒ Object
414 415 416 417 418 419 420 421 |
# File 'lib/queries/taxon_name/filter.rb', line 414 def validity_facet return nil if validity.nil? if validity table[:id].eq(table[:cached_valid_taxon_name_id]) else table[:id].not_eq(table[:cached_valid_taxon_name_id]) end end |
#with_etymology_facet ⇒ Object
Returns Scope.
257 258 259 260 261 262 |
# File 'lib/queries/taxon_name/filter.rb', line 257 def with_etymology_facet return nil if etymology.nil? etymology ? ::TaxonName.where.not(etymology: nil) : ::TaxonName.where(etymology: nil) end |
#with_nomenclature_code ⇒ Arel::Nodes::Grouping?
Returns and clause.
371 372 373 374 |
# File 'lib/queries/taxon_name/filter.rb', line 371 def with_nomenclature_code return nil if nomenclature_code.nil? table[:rank_class].matches(nomenclature_code) end |
#with_nomenclature_group ⇒ Arel::Nodes::Grouping?
Returns and clause.
364 365 366 367 |
# File 'lib/queries/taxon_name/filter.rb', line 364 def with_nomenclature_group return nil if nomenclature_group.nil? table[:rank_class].matches(nomenclature_group) end |
#year_facet ⇒ Object
404 405 406 407 |
# File 'lib/queries/taxon_name/filter.rb', line 404 def year_facet return nil if year.blank? table[:cached_author_year].matches('%' + year + '%') end |