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
89 90 91 |
# File 'app/helpers/spree/filters_helper.rb', line 89 def all_option_values_scope @all_option_values_scope ||= Spree::OptionValue.for_products(storefront_products_scope).distinct end |
#default_storefront_filter_values_scope ⇒ Object
77 78 79 |
# File 'app/helpers/spree/filters_helper.rb', line 77 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
22 23 24 |
# File 'app/helpers/spree/filters_helper.rb', line 22 def default_storefront_products_for_filters @default_storefront_products_for_filters ||= products_for_filters_default_scope.unscope(:order) end |
#filter_form_fields ⇒ Object
146 147 148 149 150 |
# File 'app/helpers/spree/filters_helper.rb', line 146 def filter_form_fields return '' if products_filters_params.blank? map_filters_params_to_form_fields(products_filters_params) end |
#filter_price_range ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'app/helpers/spree/filters_helper.rb', line 51 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
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'app/helpers/spree/filters_helper.rb', line 64 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
108 109 110 111 112 113 114 |
# File 'app/helpers/spree/filters_helper.rb', line 108 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
116 117 118 119 120 121 122 |
# File 'app/helpers/spree/filters_helper.rb', line 116 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
93 94 95 96 97 98 99 100 101 102 |
# File 'app/helpers/spree/filters_helper.rb', line 93 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
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'app/helpers/spree/filters_helper.rb', line 152 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
178 179 180 181 182 183 184 |
# File 'app/helpers/spree/filters_helper.rb', line 178 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
26 27 28 29 30 31 32 33 34 |
# File 'app/helpers/spree/filters_helper.rb', line 26 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
36 37 38 39 40 41 42 43 44 |
# File 'app/helpers/spree/filters_helper.rb', line 36 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
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'app/helpers/spree/filters_helper.rb', line 124 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
46 47 48 49 |
# File 'app/helpers/spree/filters_helper.rb', line 46 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
138 139 140 141 142 143 144 |
# File 'app/helpers/spree/filters_helper.rb', line 138 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 |
# File 'app/helpers/spree/filters_helper.rb', line 10 def products_for_filters_scope(except_filters: []) finder_params = default_products_finder_params finder_params[:filter] = finder_params[:filter].except(*except_filters) if except_filters.any? products = storefront_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
171 172 173 174 175 176 |
# File 'app/helpers/spree/filters_helper.rb', line 171 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
81 82 83 84 85 86 87 |
# File 'app/helpers/spree/filters_helper.rb', line 81 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
18 19 20 |
# File 'app/helpers/spree/filters_helper.rb', line 18 def storefront_products_for_filters @storefront_products_for_filters ||= products_for_filters_scope end |
#storefront_products_for_taxon_filters ⇒ Object
104 105 106 |
# File 'app/helpers/spree/filters_helper.rb', line 104 def storefront_products_for_taxon_filters @storefront_products_for_taxon_filters ||= products_for_filters_scope(except_filters: [:taxons, :taxonomy_ids]) end |
#taxons_filtered? ⇒ Boolean
186 187 188 |
# File 'app/helpers/spree/filters_helper.rb', line 186 def taxons_filtered? permitted_products_params.dig(:filter, :taxon_ids)&.any? end |