Module: Spree::Core::ProductFilters
- Defined in:
- lib/spree/core/product_filters.rb
Overview
See specific filters below for concrete examples.
Class Method Summary collapse
-
.all_taxons ⇒ Object
Filtering by the list of all taxons.
- .brand_filter ⇒ Object
- .format_price(amount) ⇒ Object
- .price_filter ⇒ Object
- .selective_brand_filter(taxon = nil) ⇒ Object
-
.taxons_below(taxon) ⇒ Object
Provide filtering on the immediate children of a taxon.
Class Method Details
.all_taxons ⇒ Object
Filtering by the list of all taxons
Similar idea as above, but we don’t want the descendants’ products, hence it uses one of the auto-generated scopes from Ransack.
idea: expand the format to allow nesting of labels?
183 184 185 186 187 188 189 190 191 |
# File 'lib/spree/core/product_filters.rb', line 183 def ProductFilters.all_taxons taxons = Spree::Taxonomy.all.map { |t| [t.root] + t.root.descendants }.flatten { name: 'All taxons', scope: :taxons_id_equals_any, labels: taxons.sort_by(&:name).map { |t| [t.name, t.id] }, conds: nil # not needed } end |
.brand_filter ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/spree/core/product_filters.rb', line 105 def ProductFilters.brand_filter brand_property = Spree::Property.find_by(name: 'brand') brands = brand_property ? Spree::ProductProperty.where(property_id: brand_property.id).pluck(:value).uniq.map(&:to_s) : [] pp = Spree::ProductProperty.arel_table conds = Hash[*brands.map { |b| [b, pp[:value].eq(b)] }.flatten] { name: I18n.t('spree.taxonomy_brands_name'), scope: :brand_any, conds: conds, labels: (brands.sort).map { |k| [k, k] } } end |
.format_price(amount) ⇒ Object
64 65 66 |
# File 'lib/spree/core/product_filters.rb', line 64 def ProductFilters.format_price(amount) Spree::Money.new(amount) end |
.price_filter ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/spree/core/product_filters.rb', line 68 def ProductFilters.price_filter v = Spree::Price.arel_table conds = [ [ Spree.t(:under_price, price: format_price(10)) , v[:amount].lteq(10)], [ "#{format_price(10)} - #{format_price(15)}" , v[:amount].in(10..15)], [ "#{format_price(15)} - #{format_price(18)}" , v[:amount].in(15..18)], [ "#{format_price(18)} - #{format_price(20)}" , v[:amount].in(18..20)], [ Spree.t(:or_over_price, price: format_price(20)) , v[:amount].gteq(20)]] { name: Spree.t(:price_range), scope: :price_range_any, conds: Hash[*conds.flatten], labels: conds.map { |k,v| [k, k] } } end |
.selective_brand_filter(taxon = nil) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/spree/core/product_filters.rb', line 141 def ProductFilters.selective_brand_filter(taxon = nil) taxon ||= Spree::Taxonomy.first.root brand_property = Spree::Property.find_by(name: 'brand') scope = Spree::ProductProperty.where(property: brand_property). joins(product: :taxons). where("#{Spree::Taxon.table_name}.id" => [taxon] + taxon.descendants) brands = scope.pluck(:value).uniq { name: 'Applicable Brands', scope: :selective_brand_any, labels: brands.sort.map { |k| [k, k] } } end |
.taxons_below(taxon) ⇒ Object
Provide filtering on the immediate children of a taxon
This doesn’t fit the pattern of the examples above, so there’s a few changes. Firstly, it uses an existing scope which was not built for filtering - and so has no need of a conditions mapping, and secondly, it has a mapping of name to the argument type expected by the other scope.
This technique is useful for filtering on objects (by passing ids) or with a scope that can be used directly (eg. testing only ever on a single property).
This scope selects products in any of the active taxons or their children.
167 168 169 170 171 172 173 174 175 |
# File 'lib/spree/core/product_filters.rb', line 167 def ProductFilters.taxons_below(taxon) return Spree::Core::ProductFilters.all_taxons if taxon.nil? { name: 'Taxons under ' + taxon.name, scope: :taxons_id_in_tree_any, labels: taxon.children.sort_by(&:position).map { |t| [t.name, t.id] }, conds: nil } end |