Module: ProductFilters

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

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 descendents’ products, hence it uses one of the auto-generated scopes from SearchLogic.

idea: expand the format to allow nesting of labels?



166
167
168
169
170
171
172
173
# File 'lib/product_filters.rb', line 166

def ProductFilters.all_taxons
  taxons = Taxonomy.all.map {|t| [t.root] + t.root.descendents }.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



85
86
87
88
89
90
91
92
93
94
# File 'lib/product_filters.rb', line 85

def ProductFilters.brand_filter
  brands = ProductProperty.find_all_by_property_id(@@brand_property).map(&:value).uniq
  conds  = Hash[*brands.map {|b| [b, "p_brand.value = '#{b}'"]}.flatten]
  conds["No brand"] = "p_brand.value is NULL"
  { :name   => "All Brands",
    :scope  => :brand_any,
    :conds  => conds,
    :labels => (brands.sort + ["No brand"]).map {|k| [k,k]}
  }
end

.price_filterObject



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/product_filters.rb', line 51

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



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/product_filters.rb', line 120

def ProductFilters.selective_brand_filter(taxon = nil)
  if taxon.nil? 
    taxon = Taxonomy.first.root 
  end 
  all_brands = ProductProperty.find_all_by_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.descendents])
  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.



151
152
153
154
155
156
157
158
# File 'lib/product_filters.rb', line 151

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