Class: Huginn::Searchable::Query
- Inherits:
-
Object
- Object
- Huginn::Searchable::Query
- Defined in:
- lib/huginn/searchable/query.rb
Overview
Builds a tolerant full-text search relation over a model's searchable columns. The matching predicate per column is driven by Huginn.configuration.search_strategy (:pg_trgm, :full_text, :unaccent, :simple — or an Array of them combined with OR).
Columns are split in two groups following the datatable pattern:
* the model's own columns -> direct fuzzy predicates on the base WHERE
* association columns -> reverse semi-join subqueries anchored on
the first FK/has_many hop, so the base
table is never re-scanned:
belongs_to -> base[fk] IN (SELECT DISTINCT t1[pk] FROM t1 ...)
has_many -> base[pk] IN (SELECT DISTINCT t1[fk] FROM t1 ...)
Through/hand-joined chains keep the generic fallback:
base IN (SELECT DISTINCT base FROM base JOIN
The base relation never carries joins, so every match group stays one query and the count remains a plain COUNT(*). Multiple association chains produce one subquery each, combined with OR.
Class Method Summary collapse
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(model, value, options = {}) ⇒ Query
constructor
A new instance of Query.
Constructor Details
#initialize(model, value, options = {}) ⇒ Query
Returns a new instance of Query.
34 35 36 37 38 39 |
# File 'lib/huginn/searchable/query.rb', line 34 def initialize(model, value, = {}) @model = model @value = value.to_s @options = @distinct = .fetch(:distinct, true) end |
Class Method Details
.call(model, value, options = {}) ⇒ Object
30 31 32 |
# File 'lib/huginn/searchable/query.rb', line 30 def self.call(model, value, = {}) new(model, value, ).call end |
Instance Method Details
#call ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/huginn/searchable/query.rb', line 41 def call relation = @model.all return apply_distinct(relation) if @value.strip.empty? resolution = resolve_columns predicates = fuzzy_predicates(resolution.fetch(:own)) resolution.fetch(:associations).each do |_chain, group| predicate = association_predicate(group) predicates << predicate if predicate end return apply_distinct(relation) if predicates.empty? apply_distinct(relation.where(predicates.reduce(&:or))) end |