Search code examples
ruby-on-railssearchkick

Searchkick get all results when using pagination


I have the following search query for products using searchkick:

def index
  @filter = params[:filter].blank? ? nil : Search.find(params[:filter])

  if @filter.present?
      @products = @filter.products(set_order_column(@sort), @direction, params[:page], @per_page)
  else
      query = @query.presence || "*"

      @products = Product.search(
        query, 
        where: {
          active: true
        }, 
        page: params[:page], 
        per_page: @per_page, 
        order: [{
          "#{set_order_column(@sort)}" => "#{@direction}"
        }],
        misspellings: { distance: 2 },
        fields: fields)
  end

  @filter_product_ids = @products.map(&:id)
end

There is the variable filter_product_ids where I need to store all results not filtered results by @per_page. Is it possible to do that? Right now, there are results just for results @per_page.

The goal to get all the results without pagination is to get uniq values for all products used to various product categorization for filtering on the website.

Thank you for any hints, Miroslav


Solution

  • My solution is to put this in it's own class (service class), then

    class ProductFilter
      attr_reader :search_params, :search_query, :pagination_params
    
      def initialize(search_params, search_query, pagination_params)
        @search_params = search_params
        @search_query = search_query
        @pagination_params = pagination_params
      end
    
      # Will return all records from searchkick, unpaginated
      def filtered_products
        Product.search(search_query, search_param_stuff)
      end
    
      # Will return all filtered_products & then paginate on that object
      def paginated_products
        filtered_products.records.paginate(pagination_params)
      end
    
      private
      def search_param_stuff
        search_params
      end
    end
    

    In any case, searchkick's method for pagination actually works on the searchkick records object, so you can just pull the ES query (without passing in pagination params) in one method, then paginate on the filtered_products.records.