From 98337f23342c91d0be6ef52cfffc428cc907f0e4 Mon Sep 17 00:00:00 2001 From: clemkeirua Date: Fri, 3 Apr 2020 16:07:18 +0200 Subject: [PATCH] recherche usager full-text avec 1 resultat --- app/controllers/users/dossiers_controller.rb | 10 ++++----- app/services/dossier_search_service.rb | 23 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index c69c4d1d1..38e285248 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -219,13 +219,13 @@ module Users end def recherche - @dossier_id = params[:q] - dossier = current_user.dossiers.find_by(id: @dossier_id) + @search_terms = params[:q] + @dossiers = DossierSearchService.matching_dossiers_for_user(@search_terms, current_user) - if dossier - redirect_to url_for_dossier(dossier) + if @dossiers.present? + redirect_to url_for_dossier(@dossiers.first) else - flash.alert = "Vous n’avez pas de dossier avec le nº #{@dossier_id}." + flash.alert = "Vous n’avez pas de dossier contenant «#{@search_terms}»." redirect_to dossiers_path end end diff --git a/app/services/dossier_search_service.rb b/app/services/dossier_search_service.rb index a161e8e50..67308babb 100644 --- a/app/services/dossier_search_service.rb +++ b/app/services/dossier_search_service.rb @@ -4,6 +4,11 @@ class DossierSearchService .presence || dossier_by_full_text_for_instructeur(search_terms, instructeur) end + def self.matching_dossiers_for_user(search_terms, user) + dossier_by_exact_id_for_user(search_terms, user) + .presence || dossier_by_full_text_for_user(search_terms, user.dossiers) || dossier_by_full_text_for_user(search_terms, user.dossiers_invites) + end + private def self.dossier_by_exact_id_for_instructeur(search_terms, instructeur) @@ -26,6 +31,24 @@ class DossierSearchService false end + def self.dossier_by_full_text_for_user(search_terms, dossiers) + ts_vector = "to_tsvector('french', search_terms)" + ts_query = "to_tsquery('french', #{Dossier.connection.quote(to_tsquery(search_terms))})" + + dossiers + .where("#{ts_vector} @@ #{ts_query}") + .order("COALESCE(ts_rank(#{ts_vector}, #{ts_query}), 0) DESC") + end + + def self.dossier_by_exact_id_for_user(search_terms, user) + id = search_terms.to_i + if id != 0 && id_compatible?(id) # Sometimes user is searching dossiers with a big number (ex: SIRET), ActiveRecord can't deal with them and throws ActiveModel::RangeError. id_compatible? prevents this. + Dossier.where(id: user.dossiers.where(id: id) + user.dossiers_invites.where(id: id)).distinct + else + Dossier.none + end + end + def self.dossier_by_full_text_for_instructeur(search_terms, instructeur) ts_vector = "to_tsvector('french', search_terms || private_search_terms)" ts_query = "to_tsquery('french', #{Dossier.connection.quote(to_tsquery(search_terms))})"