Class: Collavre::Creatives::Filters::SearchFilter
- Inherits:
-
BaseFilter
- Object
- BaseFilter
- Collavre::Creatives::Filters::SearchFilter
- Defined in:
- app/services/collavre/creatives/filters/search_filter.rb
Constant Summary collapse
- MAX_SEARCH_WORDS =
5
Instance Method Summary collapse
- #active? ⇒ Boolean
- #match ⇒ Object
-
#matched_relation ⇒ Object
The matching rows as an ActiveRecord relation (ids not yet materialized), so callers that need to order/window in SQL can wrap it as a subquery instead of plucking the whole match set into Ruby first.
Methods inherited from BaseFilter
Constructor Details
This class inherits a constructor from Collavre::Creatives::Filters::BaseFilter
Instance Method Details
#active? ⇒ Boolean
7 8 9 |
# File 'app/services/collavre/creatives/filters/search_filter.rb', line 7 def active? params[:search].present? end |
#match ⇒ Object
11 12 13 |
# File 'app/services/collavre/creatives/filters/search_filter.rb', line 11 def match matched_relation&.pluck(:id) || [] end |
#matched_relation ⇒ Object
The matching rows as an ActiveRecord relation (ids not yet materialized), so callers that need to order/window in SQL can wrap it as a subquery instead of plucking the whole match set into Ruby first. Returns nil when the search has no usable terms. Keeps the left_joins(:comments).distinct shape (a creative matches when one comment row satisfies every word together with the description) — an EXISTS rewrite would change that semantics, so it stays a joined+distinct relation.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'app/services/collavre/creatives/filters/search_filter.rb', line 22 def matched_relation words = params[:search].to_s.strip.split(/\s+/).first(MAX_SEARCH_WORDS) return nil if words.empty? # Build AND conditions: each word must appear in description OR comments conditions = [] binds = {} words.each_with_index do |word, i| key = :"q#{i}" binds[key] = "%#{sanitize_like(word.downcase)}%" conditions << "(LOWER(creatives.description) LIKE :#{key} ESCAPE '\\' " \ "OR LOWER(comments.content) LIKE :#{key} ESCAPE '\\')" end scope .left_joins(:comments) .where(conditions.join(" AND "), **binds) .distinct end |