class Brainstem::QueryStrategies::FilterAndSearch

Public Instance Methods

execute(scope) click to toggle source
# File lib/brainstem/query_strategies/filter_and_search.rb, line 4
def execute(scope)
  scope, ordered_search_ids = run_search(scope, filter_includes.map(&:name))
  scope = @options[:primary_presenter].apply_filters_to_scope(scope, @options[:params], @options)

  if ordering?
    count_scope = scope
    scope = paginate(scope)
    scope = @options[:primary_presenter].apply_ordering_to_scope(scope, @options[:params])
    primary_models = evaluate_scope(scope)
    count = evaluate_count(count_scope)
  else
    filtered_ids = scope.pluck(:id)
    count = filtered_ids.size

    # order a potentially large set of ids
    ordered_ids = order_for_search(filtered_ids, ordered_search_ids, with_ids: true)
    ordered_paginated_ids = paginate_array(ordered_ids)

    scope = scope.unscoped.where(id: ordered_paginated_ids)
    # not using `evaluate_scope` because we are already instantiating
    # a scope based on ids
    primary_models = scope.to_a

    # Once hydrated, a page worth of models needs to be reordered
    # due to the `scope.unscoped.where(id: ...` clobbering our ordering
    primary_models = order_for_search(primary_models, ordered_paginated_ids)
  end

  [primary_models, count]
end

Private Instance Methods

ordering?() click to toggle source
# File lib/brainstem/query_strategies/filter_and_search.rb, line 55
def ordering?
  sort_name = @options[:params][:order].to_s.split(":").first
  sort_orders = @options[:primary_presenter].configuration[:sort_orders]
  sort_name.present? && sort_orders && sort_orders[sort_name].present?
end
paginate(scope) click to toggle source
# File lib/brainstem/query_strategies/filter_and_search.rb, line 61
def paginate(scope)
  limit, offset = calculate_limit_and_offset
  scope.limit(limit).offset(offset).distinct
end
paginate_array(array) click to toggle source
# File lib/brainstem/query_strategies/filter_and_search.rb, line 66
def paginate_array(array)
  limit, offset = calculate_limit_and_offset
  array.drop(offset).first(limit) # do we need to uniq this?
end