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 feature was provided.



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

def base_query
  # raise order_start_time.inspect
  raise "Missing feature" unless feature

  @scope.where(feature: feature)
end

#search_category_idObject

Handle the category_id filter



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

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.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'app/services/decidim/resource_search.rb', line 41

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

  conditions = []
  conditions << "decidim_scope_id IS NULL" if clean_scope_ids.delete("global")

  clean_scope_ids.map!(&:to_i)

  if clean_scope_ids.any?
    conditions.concat(["? = ANY(decidim_scopes.part_of)"] * clean_scope_ids.count)
    conditions << "decidim_scopes.id IN (?)"
  end

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