class Udongo::Search::Base

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: Udongo::Search::Backend - included in Udongo Udongo::Search::Frontend Udongo::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.

Attributes

controller[R]
term[R]

Public Class Methods

new(term, controller: nil, namespace: nil) click to toggle source
# File lib/udongo/search/base.rb, line 27
def initialize(term, controller: nil, namespace: nil)
  @term = Udongo::Search::Term.new(term, controller: controller)
  @controller = controller
  @namespace = namespace
end

Public Instance Methods

class_exists?(class_name) click to toggle source
# File lib/udongo/search/base.rb, line 33
def class_exists?(class_name)
  klass = Module.const_get(class_name)
  return klass.is_a?(Class)
rescue NameError
  return false
end
indices() click to toggle source
# File lib/udongo/search/base.rb, line 40
def indices
  # Having the searchmodules sorted by weight returns indices in the
  # correct order.
  @indices ||= SearchModule.weighted.inject([]) do |stack, m|
    # 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.
    stack << m.indices
              .where('search_indices.value LIKE ?', "%#{term.value}%")
              .group([:searchable_type, :searchable_id])
  end.flatten
end
namespace() click to toggle source
# File lib/udongo/search/base.rb, line 53
def namespace
  # This looks daft, but it gives us a foot in the door for when a frontend
  # search is triggered in the backend.
  return @namespace unless @namespace.nil?
  return 'Frontend' if controller.nil?
  controller.class.parent.to_s
end
result_object(index) click to toggle source

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).

# File lib/udongo/search/base.rb, line 64
def result_object(index)
  klass = "Udongo::Search::ResultObjects::#{namespace}::#{index.searchable_type}"
  klass = 'Udongo::Search::ResultObjects::Base' unless result_object_exists?(klass)
  klass.constantize.new(index, search_context: self)
end
result_object_exists?(name) click to toggle source
# File lib/udongo/search/base.rb, line 70
def result_object_exists?(name)
  class_exists?(name) && name.constantize.method_defined?(:build_html)
end