Class: Compass::Search::Provider

Inherits:
Object
  • Object
show all
Includes:
Rendering
Defined in:
lib/compass/search/provider.rb

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Rendering

#render, #view_context

Constructor Details

#initialize(**context) ⇒ Provider

Returns a new instance of Provider.



66
67
68
69
# File 'lib/compass/search/provider.rb', line 66

def initialize(**context)
  @context = context
  context.each { |key, value| define_singleton_method(key) { value } }
end

Class Attribute Details

.providersObject (readonly)

Returns the value of attribute providers.



17
18
19
# File 'lib/compass/search/provider.rb', line 17

def providers
  @providers
end

Class Method Details

.available_provider_namesObject



58
59
60
61
62
63
# File 'lib/compass/search/provider.rb', line 58

def available_provider_names
  Compass.config.search.providers.map do |provider|
    provider_class = constantize_provider(provider)
    normalize_name(provider_class)
  end
end

.constantize_provider(provider) ⇒ Object

Handles both class objects and string class names



20
21
22
# File 'lib/compass/search/provider.rb', line 20

def constantize_provider(provider)
  provider.is_a?(String) ? provider.constantize : provider
end

.find_by_name(name) ⇒ Object



51
52
53
54
55
56
# File 'lib/compass/search/provider.rb', line 51

def find_by_name(name)
  Compass.config.search.providers.find do |provider|
    provider_class = constantize_provider(provider)
    normalize_name(provider_class) == name.to_s
  end&.then { |p| constantize_provider(p) }
end

.global_search(query, context = {}) ⇒ Object

Aggregates search results from all registered providers



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/compass/search/provider.rb', line 25

def global_search(query, context = {})
  Compass.config.search.providers.flat_map do |provider|
    begin
      provider_class = constantize_provider(provider)
      provider_class.new(**context).search(query)
    rescue => e
      Compass.logger&.error("[ Compass::Search::Provider ] #{provider_class}: #{e.class}: #{e.message}")
      []
    end
  end
end

.normalize_name(provider_class) ⇒ Object



47
48
49
# File 'lib/compass/search/provider.rb', line 47

def normalize_name(provider_class)
  provider_class.name.demodulize.underscore.sub(/_?provider$/, "")
end

.search(query, provider_name, context = {}) ⇒ Object

Add this new class method for individual provider search



38
39
40
41
42
43
44
45
# File 'lib/compass/search/provider.rb', line 38

def search(query, provider_name, context = {})
  provider_class = find_by_name(provider_name)
  if provider_class
    provider_class.new(**context).search(query)
  else
    raise UnknownProvider.new(provider_name, available_provider_names)
  end
end

Instance Method Details

#fetch_records(query) ⇒ Object

Raises:

  • (NotImplementedError)


98
99
100
# File 'lib/compass/search/provider.rb', line 98

def fetch_records(query)
  raise NotImplementedError, "#{self.class} must implement #fetch_records"
end

#format_result(record) ⇒ Object



102
103
104
105
106
107
108
109
# File 'lib/compass/search/provider.rb', line 102

def format_result(record)
  {
    id: record.try(:id),
    label: record.try(:label) || record.try(:name) || record.try(:title) || record.try(:to_s),
    category: record.try(:category) || record.class.name.demodulize,
    tag: record.try(:tag) || record.try(:role)
  }.compact
end

#labelObject



87
88
89
# File 'lib/compass/search/provider.rb', line 87

def label
  self.class.name.demodulize.sub(/Provider$/, "").titleize
end

#log_error(error, query) ⇒ Object



111
112
113
114
115
# File 'lib/compass/search/provider.rb', line 111

def log_error(error, query)
   Compass.logger&.error(
    "[ Compass::Search::Provider ] #{self.class}: #{error.class}: #{error.message} | Query: #{query.inspect}"
  )
end

#search(query) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/compass/search/provider.rb', line 71

def search(query)
  records = fetch_records(query)
  {
    label: label,
    search_options: search_options,
    results: Array(records).map { |record| format_result(record) }.compact
  }
rescue => e
  log_error(e, query)
  {
    label: label,
    search_options: search_options,
    results: []
  }
end

#search_optionsObject



91
92
93
94
95
96
# File 'lib/compass/search/provider.rb', line 91

def search_options
  {
    keys: [ { name: "label", weight: 1 } ],
    threshold: 0.2
  }
end