Class: QuickSearch::PolymorphicQuickSearch

Inherits:
Object
  • Object
show all
Includes:
ActionView::Helpers::SanitizeHelper
Defined in:
app/queries/quick_search/polymorphic_quick_search.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(quick_searcher, options = {}) ⇒ PolymorphicQuickSearch

Returns a new instance of PolymorphicQuickSearch.



6
7
8
9
# File 'app/queries/quick_search/polymorphic_quick_search.rb', line 6

def initialize(quick_searcher, options = {})
  @quick_searcher = quick_searcher
  @logger = options[:logger] || Rails.logger
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



4
5
6
# File 'app/queries/quick_search/polymorphic_quick_search.rb', line 4

def logger
  @logger
end

Class Method Details

.find(params) ⇒ Object

This is a last in first out queue, last entry added to finding is the first evaluated



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/queries/quick_search/polymorphic_quick_search.rb', line 110

def self.find(params)
  finding(QuickSearch::CatalogItemQuickSearch)
    .finding(QuickSearch::PublicationQuickSearch)
    .finding(QuickSearch::PurchaseOrderTrackingNumberQuickSearch)
    .finding(QuickSearch::OrderTrackingNumberQuickSearch)
    .finding(QuickSearch::AddressQuickSearch)
    .finding(QuickSearch::OpportunityNameQuickSearch)
    .finding(QuickSearch::CustomerPurchaseOrderQuickSearch)
    .finding(QuickSearch::OrderCustomerReference)
    .finding(QuickSearch::OrderRecipientSearch)
    .finding(QuickSearch::OrderShippingReferenceQuickSearch)
    .finding(QuickSearch::DeliveryQuickSearch)
    .finding(QuickSearch::PhoneNumberQuickSearch)
    .finding(QuickSearch::EmailPreferenceQuickSearch)
    .finding(QuickSearch::ListUnsubscribeQuickSearch)
    .finding(QuickSearch::AccountLoginQuickSearch)
    .finding(QuickSearch::ContactPointEmailQuickSearch)
    .finding(QuickSearch::OpportunityQuickSearch)
    .finding(QuickSearch::PartyNameTextQuickSearch)
    .finding(QuickSearch::InvoicePoNumberQuickSearch)
    .finding(QuickSearch::AmazonVariationQuickSearch)
    .finding(QuickSearch::ItemQuickSearch)
    .finding(QuickSearch::CustomerNumberQuickSearch)
    .finding(QuickSearch::CreditApplicationQuickSearch)
    .finding(QuickSearch::VoucherQuickSearch)
    .finding(QuickSearch::SupportCaseQuickSearch)
    .finding(QuickSearch::RmaTrackingNumberQuickSearch)
    .finding(QuickSearch::RmaQuickSearch)
    .finding(QuickSearch::InvoiceQuickSearch)
    .finding(QuickSearch::CreditMemoQuickSearch)
    .finding(QuickSearch::PurchaseOrderQuickSearch)
    .finding(QuickSearch::QuoteQuickSearch)
    .finding(QuickSearch::RoomConfigurationQuickSearch)
    .finding(QuickSearch::CartQuickSearch)
    .finding(QuickSearch::OrderQuickSearch)
    .find(params)
end

.finding(quick_searcher) ⇒ Object



11
12
13
# File 'app/queries/quick_search/polymorphic_quick_search.rb', line 11

def self.finding(quick_searcher)
  new(QuickSearch::NullQuickSearch.new).finding(quick_searcher)
end

Instance Method Details

#find(params) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/queries/quick_search/polymorphic_quick_search.rb', line 20

def find(params)
  logger.info " QuickSearch on #{self.class.name} with params #{params} initiated"
  params[:query] = sanitize(params[:query].to_s.strip.presence)

  # Normalize inputs
  limit = (params[:limit].presence || params[:max_records]).to_i
  limit = nil if limit <= 0
  allowed_types = params[:types]
  allowed_types = allowed_types.split(',') if allowed_types.is_a?(String)
  allowed_types = Array(allowed_types).map { |t| t.to_s.strip }.reject(&:blank?).map(&:to_sym)

  # Map friendly types (e.g., 'opportunity') to the subset of QuickSearch classes that should run
  query_type_class_names = nil
  if allowed_types.any?
    case allowed_types.first
    when :contact
      query_type_class_names = ['QuickSearch::PartyNameTextQuickSearch', 'QuickSearch::PhoneNumberQuickSearch', 'QuickSearch::EmailPreferenceQuickSearch', 'QuickSearch::ListUnsubscribeQuickSearch']
    when :customer
      query_type_class_names = ['QuickSearch::PartyNameTextQuickSearch', 'QuickSearch::PhoneNumberQuickSearch', 'QuickSearch::CustomerNumberQuickSearch', 'QuickSearch::CustomerPurchaseOrderQuickSearch', 'QuickSearch::EmailPreferenceQuickSearch', 'QuickSearch::ListUnsubscribeQuickSearch']
    when :opportunity
      query_type_class_names = ['QuickSearch::OpportunityQuickSearch', 'QuickSearch::OpportunityNameQuickSearch']
    when :order
      query_type_class_names = ['QuickSearch::OrderQuickSearch', 'QuickSearch::OrderCustomerReference', 'QuickSearch::OrderRecipientSearch', 'QuickSearch::OrderShippingReferenceQuickSearch', 'QuickSearch::OrderTrackingNumberQuickSearch', 'QuickSearch::DeliveryQuickSearch']
    when :invoice
      query_type_class_names = ['QuickSearch::InvoiceQuickSearch', 'QuickSearch::InvoicePoNumberQuickSearch']
    when :quote
      query_type_class_names = ['QuickSearch::QuoteQuickSearch']
    when :support_case
      query_type_class_names = ['QuickSearch::SupportCaseQuickSearch']
    when :publication
      query_type_class_names = ['QuickSearch::PublicationQuickSearch']
    when :purchase_order
      query_type_class_names = ['QuickSearch::PurchaseOrderQuickSearch', 'QuickSearch::PurchaseOrderTrackingNumberQuickSearch']
    when :rma
      query_type_class_names = ['QuickSearch::RmaQuickSearch', 'QuickSearch::RmaTrackingNumberQuickSearch']
    when :voucher
      query_type_class_names = ['QuickSearch::VoucherQuickSearch']
    when :item
      query_type_class_names = ['QuickSearch::ItemQuickSearch', 'QuickSearch::AmazonVariationQuickSearch']
    when :credit_memo
      query_type_class_names = ['QuickSearch::CreditMemoQuickSearch']
    end
  end

  # To ensure we can fill the limit after filtering, over-fetch when a type filter is present
  default_max = QuickSearch::BaseQuickSearch::DEFAULT_MAX_RECORDS
  effective_limit = limit || default_max
  fetch_limit = allowed_types.any? ? [effective_limit * 10, 1000].min : limit
  # Signal to quick searchers to not clamp to their internal query_limit when we explicitly
  # asked for a higher limit. This lets us actually gather enough records before filtering.
  params[:force_limit] = true if fetch_limit && fetch_limit > default_max

  # If we resolved a subset of quick search classes to run, pass it down using :query_type
  # so BaseQuickSearch#handles_query_type? will gate execution. Provide both classes and friendly symbols.
  params[:query_type] = query_type_class_names + allowed_types if query_type_class_names
  # Pass entity type filter to searchers that can return multiple entity classes (e.g., phone numbers)
  params[:entity_types] = allowed_types if allowed_types.any?
  raw_results = @quick_searcher.find(params, fetch_limit)
  raw_results = raw_results.uniq

  if allowed_types.any?
    raw_results = raw_results.select do |r|
      # If the result is a Party subclass (Contact, Customer, etc.), filter by its class
      if r.is_a?(Party)
        allowed_types.include?(r.class.name.tableize.singularize.to_sym)
      # If the result references a party (e.g., ContactPoint), assume the underlying searcher
      # already applied entity type constraints via params[:entity_types], so keep it.
      elsif r.respond_to?(:party_id)
        true
      else
        allowed_types.include?(r.class.name.tableize.singularize.to_sym)
      end
    rescue StandardError
      false
    end
  end

  # Eager-load associations commonly used by presenters to prevent N+1s
  begin
    contacts = raw_results.select { |r| r.is_a?(Contact) }
    ActiveRecord::Associations::Preloader.new.preload(contacts, :customer) if contacts.any?
  rescue StandardError
    # No-op: if non-AR objects included, skip preloading safely
  end

  # Finally, cap to requested limit or default
  raw_results.first(effective_limit)
end

#finding(quick_search_klass) ⇒ Object



15
16
17
18
# File 'app/queries/quick_search/polymorphic_quick_search.rb', line 15

def finding(quick_search_klass)
  new_quick_search = quick_search_klass.new(@quick_searcher)
  self.class.new(new_quick_search)
end