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
91 92 93 |
# File 'app/helpers/spree/filters_helper.rb', line 91 def all_option_values_scope @all_option_values_scope ||= Spree::OptionValue.for_products(storefront_products_scope).distinct end |
#default_storefront_filter_values_scope ⇒ Object
79 80 81 |
# File 'app/helpers/spree/filters_helper.rb', line 79 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
148 149 150 151 152 |
# File 'app/helpers/spree/filters_helper.rb', line 148 def filter_form_fields return '' if products_filters_params.blank? map_filters_params_to_form_fields(products_filters_params) end |
#filter_price_range ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'app/helpers/spree/filters_helper.rb', line 53 def filter_price_range @filter_price_range ||= begin products = products_for_filters_scope(except_filters: [:price]) Rails.cache.fetch(["price-range", products.cache_key_with_version, current_currency], expires_in: 1.day) do { min: Spree::Price.for_products(products, current_currency).minimum(:amount) || 0.to_d, max: Spree::Price.for_products(products, current_currency).maximum(:amount) || 0.to_d } end end end |
#filter_stock_count ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'app/helpers/spree/filters_helper.rb', line 66 def filter_stock_count @filter_stock_count ||= begin products = products_for_filters_scope(except_filters: [:purchasable, :out_of_stock]) Rails.cache.fetch(["stock-count", products.cache_key_with_version], expires_in: 1.day) do { in_stock: products.in_stock.distinct.count, out_of_stock: products.out_of_stock.distinct.count } end end end |
#filter_taxon_ids ⇒ Object
110 111 112 113 114 115 116 |
# File 'app/helpers/spree/filters_helper.rb', line 110 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
118 119 120 121 122 123 124 |
# File 'app/helpers/spree/filters_helper.rb', line 118 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
95 96 97 98 99 100 101 102 103 104 |
# File 'app/helpers/spree/filters_helper.rb', line 95 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).ids 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
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'app/helpers/spree/filters_helper.rb', line 154 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
180 181 182 183 184 185 186 |
# File 'app/helpers/spree/filters_helper.rb', line 180 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 35 36 |
# File 'app/helpers/spree/filters_helper.rb', line 28 def product_filters_aggregations @product_filters_aggregations ||= Rails.cache.fetch(["product-filters-aggregations", storefront_products_for_filters.cache_key_with_version], expires_in: 1.day) do storefront_products_for_filters. joins(variants_including_master: :option_values). group("#{Spree::OptionValue.table_name}.id"). distinct. count end end |
#product_single_filter_aggregations ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'app/helpers/spree/filters_helper.rb', line 38 def product_single_filter_aggregations @product_single_filter_aggregations ||= Rails.cache.fetch(["product-single-filter-aggregations", default_storefront_products_for_filters.cache_key_with_version], expires_in: 1.day) do default_storefront_products_for_filters. joins(variants_including_master: :option_values). group("#{Spree::OptionValue.table_name}.id"). distinct. count end end |
#product_taxon_aggregations ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'app/helpers/spree/filters_helper.rb', line 126 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
48 49 50 51 |
# File 'app/helpers/spree/filters_helper.rb', line 48 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
140 141 142 143 144 145 146 |
# File 'app/helpers/spree/filters_helper.rb', line 140 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
173 174 175 176 177 178 |
# File 'app/helpers/spree/filters_helper.rb', line 173 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
83 84 85 86 87 88 89 |
# File 'app/helpers/spree/filters_helper.rb', line 83 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
106 107 108 |
# File 'app/helpers/spree/filters_helper.rb', line 106 def storefront_products_for_taxon_filters @storefront_products_for_taxon_filters ||= products_for_filters_scope(except_filters: [:taxons, :taxonomy_ids]) end |
#taxons_filtered? ⇒ Boolean
188 189 190 |
# File 'app/helpers/spree/filters_helper.rb', line 188 def taxons_filtered? permitted_products_params.dig(:filter, :taxon_ids)&.any? end |