Module: Spree::FiltersHelper
- Defined in:
- app/helpers/spree/filters_helper.rb
Instance Method Summary collapse
- #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
#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
136 137 138 139 140 |
# File 'app/helpers/spree/filters_helper.rb', line 136 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
98 99 100 101 102 103 104 |
# File 'app/helpers/spree/filters_helper.rb', line 98 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
106 107 108 109 110 111 112 |
# File 'app/helpers/spree/filters_helper.rb', line 106 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
83 84 85 86 87 88 89 90 91 92 |
# File 'app/helpers/spree/filters_helper.rb', line 83 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
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'app/helpers/spree/filters_helper.rb', line 142 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
168 169 170 171 172 173 174 |
# File 'app/helpers/spree/filters_helper.rb', line 168 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
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'app/helpers/spree/filters_helper.rb', line 114 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
128 129 130 131 132 133 134 |
# File 'app/helpers/spree/filters_helper.rb', line 128 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
161 162 163 164 165 166 |
# File 'app/helpers/spree/filters_helper.rb', line 161 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 Spree::OptionValue.for_products(storefront_products_for_filters).distinct 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
94 95 96 |
# File 'app/helpers/spree/filters_helper.rb', line 94 def storefront_products_for_taxon_filters @storefront_products_for_taxon_filters ||= products_for_filters_scope(except_filters: [:taxons]) end |
#taxons_filtered? ⇒ Boolean
176 177 178 |
# File 'app/helpers/spree/filters_helper.rb', line 176 def taxons_filtered? permitted_products_params.dig(:filter, :taxon_ids)&.any? end |