environment_finder.rb
4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
class EnvironmentFinder
def initialize env
@environment = env
end
def find(asset, query = nil, options={}, finder_method = 'paginate')
@region = Region.find_by_id(options.delete(:region)) if options.has_key?(:region)
if @region && options[:within]
options[:origin] = [@region.lat, @region.lng]
else
options.delete(:within)
end
product_category = options.delete(:product_category)
date_range = options.delete(:date_range)
# FIXME this test is in more than one place
if finder_method == 'paginate'
options = {:page => 1, :per_page => options.delete(:limit)}.merge(options)
end
if query.blank?
# FIXME this test is in more than one place
if finder_method == 'paginate'
options = {:order => "#{asset_table(asset)}.name"}.merge(options)
end
if product_category && asset == :products
@environment.send(asset).send(finder_method, :all, options.merge(:include => 'product_categorizations', :conditions => ['product_categorizations.category_id = (?)', product_category.id]))
elsif product_category && asset == :enterprises
@environment.send(asset).send(finder_method, :all, options.merge( :order => 'profiles.name', :joins => 'inner join products on (products.enterprise_id = profiles.id) inner join product_categorizations on (product_categorizations.product_id = products.id)', :conditions => ['product_categorizations.category_id = (?)', product_category.id]))
else
if asset == :events
# Ignore pagination for asset events
options.delete(:per_page)
options.delete(:page)
if date_range
@environment.send(asset).send('find', :all, options.merge(:conditions => [
'start_date BETWEEN :start_day AND :end_day OR end_date BETWEEN :start_day AND :end_day',
{:start_day => date_range.first, :end_day => date_range.last}
]))
else
@environment.send(asset).send('find', :all, options)
end
else
@environment.send(asset).send(finder_method, :all, options)
end
end
else
pg_options = {:page => options.delete(:page), :per_page => options.delete(:per_page)}
solr_options = {:facets => options.delete(:facets)}
if product_category && asset == :products
# SECURITY no risk of SQL injection, since product_category_ids comes from trusted source
ret = @environment.send(asset).find_by_contents(query, pg_options, solr_options, options.merge({:include => 'product_categorizations', :conditions => 'product_categorizations.category_id = (%s)' % product_category.id }))
elsif product_category && asset == :enterprises
ret = @environment.send(asset).find_by_contents(query, pg_options, solr_options, options.merge(:joins => 'inner join product_categorizations on (product_categorizations.product_id = products.id)', :include => 'products', :conditions => "product_categorizations.category_id = (#{product_category.id})"))
else
ret = @environment.send(asset).find_by_contents(query, pg_options, solr_options, options)
end
if solr_options[:facets].nil?
ret[:results]
else
ret
end
end
end
def recent(asset, limit = nil)
find(asset, nil, :limit => limit)
end
def product_categories_count(asset, product_categories_ids, objects_ids=nil)
conditions = ['product_categorizations.category_id in (?)', product_categories_ids]
if asset == :products
if objects_ids
conditions[0] += ' and product_categorizations.product_id in (?)'
conditions << objects_ids
end
ProductCategory.find(:all, :select => 'categories.id, count(*) as total', :joins => 'inner join product_categorizations on (product_categorizations.category_id = categories.id)', :group => 'categories.id', :conditions => conditions )
elsif asset == :enterprises
if objects_ids
conditions[0] += ' and products.enterprise_id in (?)'
conditions << objects_ids
end
ProductCategory.find(
:all,
:select => 'categories.id, count(distinct products.enterprise_id) as total',
:joins => 'inner join product_categorizations on (product_categorizations.category_id = categories.id) inner join products on (products.id = product_categorizations.product_id)',
:group => 'categories.id',
:conditions => conditions
)
else
raise ArgumentError, 'only products and enterprises supported'
end.inject({}) do |results,pc|
results[pc.id]= pc.total.to_i
results
end
end
protected
def asset_class(asset)
asset.to_s.singularize.camelize.constantize
end
def asset_table(asset)
asset_class(asset).table_name
end
end