Module: ProductFilters

Included in:
Taxon
Defined in:
lib/product_filters.rb

Overview

This module is included by Taxon. In development mode that inclusion does not happen until Taxon class is loaded. Ensure that Taxon class is loaded before you try something like Product.price_range_any

Class Method Summary collapse

Class Method Details

.all_taxonsObject

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 SearchLogic.

idea: expand the format to allow nesting of labels?



178
179
180
181
182
183
184
185
# File 'lib/product_filters.rb', line 178

def ProductFilters.all_taxons
  taxons = 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_filterObject



98
99
100
101
102
103
104
105
106
# File 'lib/product_filters.rb', line 98

def ProductFilters.brand_filter
  brands = ProductProperty.where(:property_id => @@brand_property).map(&:value).compact.uniq
  conds  = Hash[*brands.map {|b| [b, "product_properties.value = '#{b}'"]}.flatten]
  { :name   => "Brands",
    :scope  => :brand_any,
    :conds  => conds,
    :labels => (brands.sort).map {|k| [k,k]}
  }
end

.price_filterObject



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/product_filters.rb', line 64

def ProductFilters.price_filter
  conds = [ [ "Under $10",    "price             <= 10" ],
            [ "$10 - $15",    "price between 10 and 15" ],
            [ "$15 - $18",    "price between 15 and 18" ],
            [ "$18 - $20",    "price between 18 and 20" ],
            [ "$20 or over",  "price             >= 20" ] ]
  { :name   => "Price Range",
    :scope  => :price_range_any,
    :conds  => Hash[*conds.flatten],
    :labels => conds.map {|k,v| [k,k]}
  }
end

.selective_brand_filter(taxon = nil) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/product_filters.rb', line 132

def ProductFilters.selective_brand_filter(taxon = nil)
  if taxon.nil?
    taxon = Taxonomy.first.root
  end
  all_brands = ProductProperty.where(:property_id => @@brand_property).map(&:value).uniq
  scope = ProductProperty.scoped(:conditions => ["property_id = ?", @@brand_property]).
                          scoped(:joins      => {:product => :taxons},
                                 :conditions => ["taxons.id in (?)", [taxon] + taxon.descendants])
  brands = scope.map {|p| p.value}

  { :name   => "Applicable Brands",
    :scope  => :selective_brand_any,
    :conds  => Hash[*all_brands.map {|m| [m, "p_colour.value like '%#{m}%'"]}.flatten],
    :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.



163
164
165
166
167
168
169
170
# File 'lib/product_filters.rb', line 163

def ProductFilters.taxons_below(taxon)
  return 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