Class: Spree::SearchProvider::Database
- Defined in:
- app/models/spree/search_provider/database.rb
Constant Summary collapse
- CUSTOM_SORT_SCOPES =
{ 'price' => :ascend_by_price, '-price' => :descend_by_price, 'best_selling' => :by_best_selling }.freeze
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
Methods inherited from Base
#ensure_index_settings!, #index, #index_batch, indexing_required?, #initialize, #reindex, #remove, #remove_by_id
Constructor Details
This class inherits a constructor from Spree::SearchProvider::Base
Instance Method Details
#search_and_filter(scope:, query: nil, filters: {}, sort: nil, page: 1, limit: 25) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/models/spree/search_provider/database.rb', line 10 def search_and_filter(scope:, query: nil, filters: {}, sort: nil, page: 1, limit: 25) # 1. Text search scope = scope.search(query) if query.present? # 2. Extract internal params before passing to Ransack category = filters.is_a?(Hash) ? filters.delete('_category') || filters.delete(:_category) : nil # 2b. Extract option value IDs — handled by scope (OR within type, AND across) option_value_ids = filters.is_a?(Hash) ? filters.delete('with_option_value_ids') || filters.delete(:with_option_value_ids) : nil # 3. Structured filtering via Ransack ransack_filters = sanitize_filters(filters) if ransack_filters.present? search = scope.ransack(ransack_filters) scope = search.result(distinct: true) end # Save scope before option filters for disjunctive facet counts = scope if option_value_ids.present? scope = scope.with_option_value_ids(Array(option_value_ids)) end # 4. Facets (before sorting to avoid computed column conflicts with count) filter_facets = build_facets(scope, category: category, option_value_ids: Array(option_value_ids), scope_before_options: ) # 5. Total count (before sorting to avoid computed column conflicts with count) total = scope.distinct.count # 6. Sorting + pagination scope = apply_sort(scope, sort) page = [page.to_i, 1].max limit = limit.to_i.clamp(1, 100) products = scope.offset((page - 1) * limit).limit(limit) SearchResult.new( products: products, filters: filter_facets[:filters], sort_options: filter_facets[:sort_options], default_sort: filter_facets[:default_sort], total_count: total, pagy: build_pagy(total, page, limit) ) end |