Class: Plok::Search::Base
- Inherits:
-
Object
- Object
- Plok::Search::Base
- Defined in:
- lib/plok/search/base.rb
Overview
The goal of the Base class is to filter our indices on the given search term. Further manipulation of individual index data into a meaningful result set (think autocomplete results) is done by extending this class.
Examples of class extensions could be: Plok::Search::Backend Plok::Search::Frontend Plok::Search::Api
The primary benefit in having these namespaced search interfaces is to provide a way for the developer to have different result objects for each resource.
Example #1: A search request for a specific Page instance in the frontend will typically return a link to said page. However, in search requests made in the backend for the same Page instance, you’d expect a link to a form in the backend Page module where you can edit the page’s contents.
Example #2: Some autocompletes in a frontend namespace might require an image or a price to be included in its body.
However these result objects are structured are also up to the developer.
Instance Attribute Summary collapse
-
#controller ⇒ Object
readonly
Returns the value of attribute controller.
-
#namespace ⇒ Object
readonly
Returns the value of attribute namespace.
-
#term ⇒ Object
readonly
Returns the value of attribute term.
Instance Method Summary collapse
- #format_search_results(indices, options = {}) ⇒ Object
-
#initialize(term, namespace: nil, controller: nil) ⇒ Base
constructor
A new instance of Base.
-
#result_object(index) ⇒ Object
In order to provide a good result set in a search autocomplete, we have to translate the raw index to a class that makes an index adhere to a certain interface (that can include links).
- #result_object_exists?(name) ⇒ Boolean
-
#search_indices(modules: []) ⇒ Object
TODO: SearchIndexCollection TODO: What if records are hidden? Make this smart and have SearchIndex#visible? TODO: See if there’s a way to pass weight through individual records.
Constructor Details
#initialize(term, namespace: nil, controller: nil) ⇒ Base
Returns a new instance of Base.
28 29 30 31 32 |
# File 'lib/plok/search/base.rb', line 28 def initialize(term, namespace: nil, controller: nil) @term = Plok::Search::Term.new(term, controller: controller) @namespace = namespace @controller = controller end |
Instance Attribute Details
#controller ⇒ Object (readonly)
Returns the value of attribute controller.
26 27 28 |
# File 'lib/plok/search/base.rb', line 26 def controller @controller end |
#namespace ⇒ Object (readonly)
Returns the value of attribute namespace.
26 27 28 |
# File 'lib/plok/search/base.rb', line 26 def namespace @namespace end |
#term ⇒ Object (readonly)
Returns the value of attribute term.
26 27 28 |
# File 'lib/plok/search/base.rb', line 26 def term @term end |
Instance Method Details
#format_search_results(indices, options = {}) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/plok/search/base.rb', line 34 def format_search_results(indices, = {}) .reverse_merge!( label_method: :build_html, value_method: :url ) indices.map do |index| result = result_object(index) { label: result.send([:label_method]), value: result.send([:value_method]) } end end |
#result_object(index) ⇒ Object
In order to provide a good result set in a search autocomplete, we have to translate the raw index to a class that makes an index adhere to a certain interface (that can include links).
53 54 55 56 57 |
# File 'lib/plok/search/base.rb', line 53 def result_object(index) klass = "Plok::Search::ResultObjects::#{@namespace.camelcase}::#{index.searchable_type}" klass = 'Plok::Search::ResultObjects::Base' unless result_object_exists?(klass) klass.constantize.new(index, search_context: self) end |
#result_object_exists?(name) ⇒ Boolean
59 60 61 |
# File 'lib/plok/search/base.rb', line 59 def result_object_exists?(name) Plok::Engine.class_exists?(name) && name.constantize.method_defined?(:build_html) end |
#search_indices(modules: []) ⇒ Object
TODO: SearchIndexCollection TODO: What if records are hidden? Make this smart and have SearchIndex#visible? TODO: See if there’s a way to pass weight through individual records.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/plok/search/base.rb', line 66 def search_indices(modules: []) modules = SearchModule.searchable.pluck(:klass) if modules.blank? # Having the searchmodules sorted by weight returns indices in the # correct order. # # The group happens to make sure we end up with just 1 copy of # a searchable result. Otherwise matches from both an indexed # Page#title and Page#description would be in the result set. @search_indices ||= SearchIndex .select('searchable_type, searchable_id, namespace') .joins('INNER JOIN search_modules ON search_indices.searchable_type = search_modules.klass') .where('search_modules.searchable': true) .where('search_modules.klass in (?)', modules) .where('search_indices.namespace = ?', @namespace) .where('search_indices.value LIKE ?', "%#{term.value}%") .group([:searchable_type, :searchable_id]) .preload(:searchable) # ".includes" for polymorphic relations end |