@@ -218,14 +218,14 @@ def fuzzy_match(
218218 when :similarity
219219 threshold ||= 0.7
220220 selection
221- . select ( "name, similarity(name, #{ clean_query } ) AS score" )
221+ . select ( "id, name, similarity(name, #{ clean_query } ) AS score" )
222222 . where ( 'similarity(name, ?) > ?' , query , threshold )
223223 . order ( 'score DESC' )
224224 . limit ( limit )
225225 when :levenshtein
226226 threshold ||= 3
227227 selection
228- . select ( "name, levenshtein(name, #{ clean_query } ) AS score" )
228+ . select ( "id, name, levenshtein(name, #{ clean_query } ) AS score" )
229229 . where ( 'levenshtein(name, ?) <= ?' , query , threshold )
230230 . order ( 'score ASC' )
231231 . limit ( limit )
@@ -650,6 +650,47 @@ def is_variant?(alt_spelling)
650650 false
651651 end
652652
653+ ##
654+ # This method always return +nil+ for names that are not at (inferred) rank
655+ # of genus or species
656+ #
657+ # Find names similar to the current one (using the cannonical spelling
658+ # from +base_name+) with Levenshtein ≤ 3, considering a search space
659+ # defined by the taxonomic rank and +among+:
660+ # - valid: All validly published names of genera or species of the same genus
661+ # - public: All publicly visible names of genera or species of the same genus
662+ # - register: All names names of genera or species of the same genus in the
663+ # same register list as this name (if any)
664+ def similar_names ( among : :valid )
665+ selection =
666+ case among . to_sym
667+ when :valid
668+ self . class . all_valid
669+ when :public
670+ self . class . all_public
671+ when :register
672+ return unless register . present?
673+ register . names
674+ else
675+ raise ArgumentError , "Unsupported search space (among): #{ among } "
676+ end
677+
678+ case inferred_rank . to_sym
679+ when :genus
680+ selection = selection . where ( rank : :genus )
681+ when :species
682+ return unless parent . present?
683+ selection = selection . where ( parent_id : parent . id )
684+ else
685+ return
686+ end
687+
688+ selection = selection . where . not ( id : id )
689+ self . class . fuzzy_match (
690+ base_name , method : :levenshtein , selection : selection
691+ )
692+ end
693+
653694 # ============ --- OUTLINKS --- ============
654695
655696 def ncbi_search_url
0 commit comments