From fc61ad4ca41dbc601ef3e519517b1d6d04c53606 Mon Sep 17 00:00:00 2001 From: Oleh Kupriianov Date: Thu, 18 Dec 2025 12:39:53 +0100 Subject: [PATCH 1/2] Fix multiple terms query in mentioning --- app/models/filter.rb | 13 +++++++++---- test/controllers/cards_controller_test.rb | 9 +++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/models/filter.rb b/app/models/filter.rb index 9bfefe176a..18f517bb64 100644 --- a/app/models/filter.rb +++ b/app/models/filter.rb @@ -32,14 +32,19 @@ def cards result = result.where(cards: { created_at: creation_window }) if creation_window result = result.closed_at_window(closure_window) if closure_window result = result.closed_by(closers) if closers.present? - result = terms.reduce(result) do |result, term| - result.mentioning(term, user: creator) - end - + result = result.mentioning(combined_fts_query, user: creator) if terms.present? result.distinct end end + def combined_fts_query + terms.map { |term| sanitize_fts_term(term) }.join(' AND ') + end + + def sanitize_fts_term(term) + term.gsub('"', '""').then { |t| "\"#{t}\"*" } + end + def empty? self.class.normalize_params(as_params).blank? end diff --git a/test/controllers/cards_controller_test.rb b/test/controllers/cards_controller_test.rb index c6c56fc83c..edc4690f25 100644 --- a/test/controllers/cards_controller_test.rb +++ b/test/controllers/cards_controller_test.rb @@ -10,8 +10,13 @@ class CardsControllerTest < ActionDispatch::IntegrationTest assert_response :success end - test "filtered index" do - get cards_path(filters(:jz_assignments).as_params.merge(term: "haggis")) + test "filtered index with single term" do + get cards_path(filters(:jz_assignments).as_params.merge(terms: ["haggis"])) + assert_response :success + end + + test "filtered index with several terms" do + get cards_path(filters(:jz_assignments).as_params.merge(terms: ["haggis", "other"])) assert_response :success end From e4ddd318a9412dc8cbc591b36f3dbb86c170c4b7 Mon Sep 17 00:00:00 2001 From: Oleh Kupriianov Date: Sun, 21 Dec 2025 15:11:06 +0100 Subject: [PATCH 2/2] Move methods to searchable concern --- app/models/card/searchable.rb | 17 +++++++++++++++++ app/models/filter.rb | 10 +--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/app/models/card/searchable.rb b/app/models/card/searchable.rb index 8cc108b23d..2055648640 100644 --- a/app/models/card/searchable.rb +++ b/app/models/card/searchable.rb @@ -10,6 +10,23 @@ module Card::Searchable end end + class_methods do + def mentioning_all(terms, user:) + query = combined_terms_fts_query(terms) + mentioning(query, user: user) + end + + private + + def combined_terms_fts_query(terms) + terms.map { |term| sanitize_fts_term(term) }.join(' AND ') + end + + def sanitize_fts_term(term) + term.gsub('"', '""').then { |t| "\"#{t}\"*" } + end + end + def search_title title end diff --git a/app/models/filter.rb b/app/models/filter.rb index 18f517bb64..7aa224f219 100644 --- a/app/models/filter.rb +++ b/app/models/filter.rb @@ -32,19 +32,11 @@ def cards result = result.where(cards: { created_at: creation_window }) if creation_window result = result.closed_at_window(closure_window) if closure_window result = result.closed_by(closers) if closers.present? - result = result.mentioning(combined_fts_query, user: creator) if terms.present? + result = result.mentioning_all(terms, user: creator) if terms.present? result.distinct end end - def combined_fts_query - terms.map { |term| sanitize_fts_term(term) }.join(' AND ') - end - - def sanitize_fts_term(term) - term.gsub('"', '""').then { |t| "\"#{t}\"*" } - end - def empty? self.class.normalize_params(as_params).blank? end