Module: Spree::FiltersHelper
- Defined in:
- app/helpers/spree/filters_helper.rb
Instance Method Summary collapse
- #all_option_values_scope ⇒ Object
- #default_storefront_filter_values_scope ⇒ Object
- #default_storefront_products_for_filters ⇒ Object
- #filter_form_fields ⇒ Object
- #filter_price_range ⇒ Object
- #filter_stock_count ⇒ Object
- #filter_taxon_ids ⇒ Object
- #filter_taxons_for_taxonomy(taxonomy) ⇒ Object
- #filter_values_for_filter(filter) ⇒ Object
- #map_filters_params_to_form_fields(filters_params, prefix_key = nil) ⇒ Object
- #price_filtered? ⇒ Boolean
- #product_filters_aggregations ⇒ Object
- #product_single_filter_aggregations ⇒ Object
- #product_taxon_aggregations ⇒ Object
- #products_count_for_filter(name, value_id) ⇒ Object
- #products_count_for_taxon(taxon) ⇒ Object
- #products_for_filters_default_scope ⇒ Object
- #products_for_filters_scope(except_filters: []) ⇒ Object
- #single_option_filter_selected?(filter_name) ⇒ Boolean
- #storefront_filter_values_scope(filter_selected) ⇒ Object
- #storefront_products_for_filters ⇒ Object
- #storefront_products_for_taxon_filters ⇒ Object
- #taxons_filtered? ⇒ Boolean
Instance Method Details
#all_option_values_scope ⇒ Object
83 84 85 |
# File 'app/helpers/spree/filters_helper.rb', line 83 def all_option_values_scope @all_option_values_scope ||= Spree::OptionValue.for_products(storefront_products_scope).distinct end |
#default_storefront_filter_values_scope ⇒ Object
71 72 73 |
# File 'app/helpers/spree/filters_helper.rb', line 71 def default_storefront_filter_values_scope @default_storefront_filter_values_scope ||= Spree::OptionValue.for_products(products_for_filters_default_scope).distinct end |
#default_storefront_products_for_filters ⇒ Object
24 25 26 |
# File 'app/helpers/spree/filters_helper.rb', line 24 def default_storefront_products_for_filters @default_storefront_products_for_filters ||= products_for_filters_default_scope.unscope(:order) end |
#filter_form_fields ⇒ Object
140 141 142 143 144 |
# File 'app/helpers/spree/filters_helper.rb', line 140 def filter_form_fields return '' if products_filters_params.blank? map_filters_params_to_form_fields(products_filters_params) end |
#filter_price_range ⇒ Object
49 50 51 52 53 54 55 56 57 58 |
# File 'app/helpers/spree/filters_helper.rb', line 49 def filter_price_range @filter_price_range ||= begin product_ids = products_for_filters_scope(except_filters: [:price]).ids { min: Spree::Price.for_products(product_ids).minimum(:amount) || 0.to_d, max: Spree::Price.for_products(product_ids).maximum(:amount) || 0.to_d } end end |
#filter_stock_count ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'app/helpers/spree/filters_helper.rb', line 60 def filter_stock_count @filter_stock_count ||= begin products_scope = products_for_filters_scope(except_filters: [:purchasable, :out_of_stock]) { in_stock: products_scope.in_stock.distinct.count, out_of_stock: products_scope.out_of_stock.distinct.count } end end |
#filter_taxon_ids ⇒ Object
102 103 104 105 106 107 108 |
# File 'app/helpers/spree/filters_helper.rb', line 102 def filter_taxon_ids @filter_taxon_ids ||= Rails.cache.fetch([spree_base_cache_key, storefront_products_for_taxon_filters, @taxon], expires_in: 1.day) do scope = storefront_products_for_taxon_filters.joins(:classifications) scope = scope.in_taxon(@taxon).unscope(:order) if @taxon.present? scope.distinct.pluck(:taxon_id) end end |
#filter_taxons_for_taxonomy(taxonomy) ⇒ Object
110 111 112 113 114 115 116 |
# File 'app/helpers/spree/filters_helper.rb', line 110 def filter_taxons_for_taxonomy(taxonomy) taxon_depth = @taxon.present? ? @taxon.depth + 1 : 1 taxonomy.taxons.where(depth: taxon_depth).order(:lft).find_all do |taxon| (taxon.cached_self_and_descendants_ids & filter_taxon_ids).any? end end |
#filter_values_for_filter(filter) ⇒ Object
87 88 89 90 91 92 93 94 95 96 |
# File 'app/helpers/spree/filters_helper.rb', line 87 def filter_values_for_filter(filter) selected = single_option_filter_selected?(filter.name) if filter.option_values.loaded? storefront_filter_values_ids = storefront_filter_values_scope(selected).pluck(:id) filter.option_values.find_all { |option_value| storefront_filter_values_ids.include?(option_value.id) } else filter.option_values.where(id: storefront_filter_values_scope(selected)) end end |
#map_filters_params_to_form_fields(filters_params, prefix_key = nil) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'app/helpers/spree/filters_helper.rb', line 146 def map_filters_params_to_form_fields(filters_params, prefix_key = nil) filters_params.to_h.map do |key, value| key = CGI.escapeHTML(key) key = [prefix_key, key].join('][') if prefix_key.present? if value.is_a?(Array) value.map do |v| v = CGI.escapeHTML(v) "<input type='hidden' name='filter[#{key}][]' value='#{v}' />" end.join elsif value.is_a?(Hash) map_filters_params_to_form_fields(value, key) else value = CGI.escapeHTML(value) "<input type='hidden' name='filter[#{key}]' value='#{value}' />" end end.join.html_safe end |
#price_filtered? ⇒ Boolean
172 173 174 175 176 177 178 |
# File 'app/helpers/spree/filters_helper.rb', line 172 def price_filtered? min_price = permitted_products_params.dig(:filter, :min_price).presence max_price = permitted_products_params.dig(:filter, :max_price).presence (min_price.present? && min_price.to_d >= filter_price_range[:min]) || (max_price.present? && max_price.to_d <= filter_price_range[:max]) end |
#product_filters_aggregations ⇒ Object
28 29 30 31 32 33 34 |
# File 'app/helpers/spree/filters_helper.rb', line 28 def product_filters_aggregations @product_filters_aggregations ||= storefront_products_for_filters. joins(variants_including_master: :option_values). group("#{Spree::OptionValue.table_name}.id"). distinct. count end |
#product_single_filter_aggregations ⇒ Object
36 37 38 39 40 41 42 |
# File 'app/helpers/spree/filters_helper.rb', line 36 def product_single_filter_aggregations @product_single_filter_aggregations ||= default_storefront_products_for_filters. joins(variants_including_master: :option_values). group("#{Spree::OptionValue.table_name}.id"). distinct. count end |
#product_taxon_aggregations ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'app/helpers/spree/filters_helper.rb', line 118 def product_taxon_aggregations @product_taxon_aggregations ||= Rails.cache.fetch([spree_base_cache_key, storefront_products_for_taxon_filters, current_store.taxons], expires_in: 1.day) do current_store.taxons. joins(:classifications). where("#{Spree::Classification.table_name}.product_id" => storefront_products_for_taxon_filters.ids). group( "#{Spree::Taxon.table_name}.id", "#{Spree::Classification.table_name}.product_id" ). unscope(:order). count("#{Spree::Classification.table_name}.product_id") end end |
#products_count_for_filter(name, value_id) ⇒ Object
44 45 46 47 |
# File 'app/helpers/spree/filters_helper.rb', line 44 def products_count_for_filter(name, value_id) aggregations = single_option_filter_selected?(name) ? product_single_filter_aggregations : product_filters_aggregations aggregations.fetch(value_id, 0) end |
#products_count_for_taxon(taxon) ⇒ Object
132 133 134 135 136 137 138 |
# File 'app/helpers/spree/filters_helper.rb', line 132 def products_count_for_taxon(taxon) taxon_self_and_descendants_ids = taxon.cached_self_and_descendants_ids aggregations = product_taxon_aggregations.select { |key, _value| key[0].in?(taxon_self_and_descendants_ids) } # We want to count unique products across the taxon tree aggregations.uniq { |key, _value| key[1] }.sum(&:last) end |
#products_for_filters_default_scope ⇒ Object
3 4 5 6 7 8 |
# File 'app/helpers/spree/filters_helper.rb', line 3 def products_for_filters_default_scope scope = storefront_products_scope scope = scope.in_taxon(@taxon) if @taxon.present? scope = scope.search_by_name(params[:q].strip).unscope(:order) if params[:q].present? scope end |
#products_for_filters_scope(except_filters: []) ⇒ Object
10 11 12 13 14 15 16 17 18 |
# File 'app/helpers/spree/filters_helper.rb', line 10 def products_for_filters_scope(except_filters: []) products_finder = Spree::Dependencies.products_finder.constantize finder_params = default_products_finder_params finder_params[:filter] = finder_params[:filter].except(*except_filters) if except_filters.any? products = products_finder.new(scope: storefront_products_scope, params: finder_params).execute current_store.products.where(id: products.unscope(:order).ids) end |
#single_option_filter_selected?(filter_name) ⇒ Boolean
165 166 167 168 169 170 |
# File 'app/helpers/spree/filters_helper.rb', line 165 def single_option_filter_selected?(filter_name) = permitted_products_params.dig(:filter, :options) || {} !price_filtered? && !taxons_filtered? && .keys.length == 1 && .key?(filter_name) end |
#storefront_filter_values_scope(filter_selected) ⇒ Object
75 76 77 78 79 80 81 |
# File 'app/helpers/spree/filters_helper.rb', line 75 def storefront_filter_values_scope(filter_selected) if filter_selected default_storefront_filter_values_scope else all_option_values_scope end end |
#storefront_products_for_filters ⇒ Object
20 21 22 |
# File 'app/helpers/spree/filters_helper.rb', line 20 def storefront_products_for_filters @storefront_products_for_filters ||= products_for_filters_scope end |
#storefront_products_for_taxon_filters ⇒ Object
98 99 100 |
# File 'app/helpers/spree/filters_helper.rb', line 98 def storefront_products_for_taxon_filters @storefront_products_for_taxon_filters ||= products_for_filters_scope(except_filters: [:taxons]) end |
#taxons_filtered? ⇒ Boolean
180 181 182 |
# File 'app/helpers/spree/filters_helper.rb', line 180 def taxons_filtered? permitted_products_params.dig(:filter, :taxon_ids)&.any? end |