Class: Decidim::ResourceSearch

Inherits:
Searchlight::Search
  • Object
show all
Defined in:
app/services/decidim/resource_search.rb

Overview

This is the base class to be used by other search services. Searchlight documentation: github.com/nathanl/searchlight

Instance Method Summary collapse

Constructor Details

#initialize(scope, options = {}) ⇒ ResourceSearch

Initialize the Searchlight::Search base class with the options provided.

scope - The scope used to create the base query options - A hash of options to modify the search. These options will be

converted to methods by SearchLight so they can be used on filter
methods. (Default {})


13
14
15
16
# File 'app/services/decidim/resource_search.rb', line 13

def initialize(scope, options = {})
  super(options)
  @scope = scope
end

Instance Method Details

#base_queryObject

Creates the SearchLight base query. Check if the option component was provided.



20
21
22
23
24
# File 'app/services/decidim/resource_search.rb', line 20

def base_query
  raise "Missing component" unless component

  @scope.where(component: component)
end

#search_category_idObject

Handle the category_id filter



27
28
29
30
31
# File 'app/services/decidim/resource_search.rb', line 27

def search_category_id
  query
    .includes(:categorization)
    .where(decidim_categorizations: { decidim_category_id: category_ids })
end

#search_scope_idObject

Handles the scope_id filter. When we want to show only those that do not have a scope_id set, we cannot pass an empty String or nil because Searchlight will automatically filter out these params, so the method will not be used. Instead, we need to pass a fake ID and then convert it inside. In this case, in order to select those elements that do not have a scope_id set we use ‘“global”` as parameter, and in the method we do the needed changes to search properly.



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/services/decidim/resource_search.rb', line 40

def search_scope_id
  clean_scope_ids = if scope_id.is_a?(Hash)
                      scope_id.values
                    else
                      [scope_id].flatten
                    end

  conditions = []
  conditions << "#{query.model_name.plural}.decidim_scope_id IS NULL" if clean_scope_ids.delete("global")
  conditions.concat(["? = ANY(decidim_scopes.part_of)"] * clean_scope_ids.count) if clean_scope_ids.any?

  query.includes(:scope).references(:decidim_scopes).where(conditions.join(" OR "), *clean_scope_ids.map(&:to_i))
end