From d2c2650deb5b9982e6119c81108fd5989a442e49 Mon Sep 17 00:00:00 2001 From: MoisesMachado Date: Fri, 11 Jul 2008 22:07:21 +0000 Subject: [PATCH] ActionItem514: made a category finder method to calculate count for product categories inside a filter --- app/controllers/public/search_controller.rb | 5 +++++ app/models/category_finder.rb | 41 +++++++++++++++++++++++++++++++++++------ test/unit/category_finder_test.rb | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------- 3 files changed, 146 insertions(+), 64 deletions(-) diff --git a/app/controllers/public/search_controller.rb b/app/controllers/public/search_controller.rb index df2b3b8..17c0114 100644 --- a/app/controllers/public/search_controller.rb +++ b/app/controllers/public/search_controller.rb @@ -89,6 +89,11 @@ class SearchController < ApplicationController def load_product_categories_menu(asset) @results[asset].uniq! # REFACTOR DUPLICATED CODE inner loop doing the same thing that outter loop + + cats = ProductCategory.menu_categories(@product_category, environment) + cats += cats.map(:children).flatten + product_categories_ids = cats.map(&:id) + @categories_menu = ProductCategory.menu_categories(@product_category, environment).map do |cat| hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, cat, @region, params[:radius], nil, nil)) childs = [] diff --git a/app/models/category_finder.rb b/app/models/category_finder.rb index 635db9c..8b4e929 100644 --- a/app/models/category_finder.rb +++ b/app/models/category_finder.rb @@ -30,12 +30,6 @@ class CategoryFinder find(asset, nil, :limit => limit) end - def count(asset, query='', options={}) - # because will_paginate needs a page - options = {:page => 1}.merge(options) - find(asset, query, options).total_entries - end - def most_commented_articles(limit=10, options={}) options = {:page => 1, :per_page => limit, :order => 'comments_count DESC'}.merge(options) Article.paginate(:all, options_for_find(Article, options)) @@ -54,6 +48,41 @@ class CategoryFinder Event.paginate(:all, {:include => :categories, :conditions => [ 'categories.id = ? and start_date >= ?', category_id, Date.today ], :order => 'start_date' }.merge(options)) end + def product_categories_count(asset, product_categories_ids, objects_ids=nil) + conditions = [ "product_categorizations.category_id in (?) and #{ProfileCategorization.table_name}.category_id = ?", product_categories_ids, category_id] + + 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) inner join products on (products.id = product_categorizations.product_id) inner join #{ProfileCategorization.table_name} on (#{ProfileCategorization.table_name}.profile_id = products.enterprise_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) inner join #{ProfileCategorization.table_name} on (#{ProfileCategorization.table_name}.profile_id = products.enterprise_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 options_for_find(klass, options={}, date_range = nil) diff --git a/test/unit/category_finder_test.rb b/test/unit/category_finder_test.rb index c9bf7d2..b90cee0 100644 --- a/test/unit/category_finder_test.rb +++ b/test/unit/category_finder_test.rb @@ -148,64 +148,6 @@ class CategoryFinderTest < ActiveSupport::TestCase assert_respond_to p2, :total_entries assert (p1 == [ent1] && p2 == [ent2]) || (p1 == [ent2] && p2 == [ent1]) # consistent paging end - - should 'count enterprises' do - count = @finder.count('enterprises') - ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1', :category_ids => [@category.id]) - assert_equal count+1, @finder.count('enterprises') - end - - should 'count people' do - count = @finder.count('people') - p = create_user('testinguser').person - p.category_ids = [@category.id] - p.save! - - assert_equal count+1, @finder.count('people') - end - should 'count products' do - count = @finder.count('products') - - ent = Enterprise.create!(:name => 'teste1', :identifier => 'teste1', :category_ids => [@category.id]) - ent.products.create!(:name => 'test prodduct') - - assert_equal count+1, @finder.count('products') - end - should 'count articles' do - ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1') - - count = @finder.count('articles') - ent1.articles.create!(:name => 'teste1', :category_ids => [@category.id]) - - assert_equal count+1, @finder.count('articles') - end - should 'count events' do - count = @finder.count('events') - ent1 = Enterprise.create!(:name => 'teste1', :identifier => 'teste1') - - Event.create!(:name => 'teste2', :profile => ent1, :start_date => Date.today, :category_ids => [@category.id]) - assert_equal count+1, @finder.count('events') - end - - should 'count enterprises with query and options' do - results = mock - - @finder.expects(:find).with('people', 'my query', kind_of(Hash)).returns(results) - - results.expects(:total_entries).returns(99) - - assert_equal 99, @finder.count('people', 'my query', {}) - end - - should 'count enterprises without query but with options' do - results = mock - - @finder.expects(:find).with('people', nil, kind_of(Hash)).returns(results) - - results.expects(:total_entries).returns(99) - - assert_equal 99, @finder.count('people', nil, {}) - end should 'not list more people than limit' do p1 = create_user('test1').person; p1.add_category(@category) @@ -384,4 +326,110 @@ class CategoryFinderTest < ActiveSupport::TestCase assert_not_includes ents, ent2 end + should 'count product categories results by products' do + pc1 = ProductCategory.create!(:name => 'test cat1', :environment => Environment.default) + pc11 = ProductCategory.create!(:name => 'test cat11', :environment => Environment.default, :parent => pc1) + pc2 = ProductCategory.create!(:name => 'test cat2', :environment => Environment.default) + pc3 = ProductCategory.create!(:name => 'test cat3', :environment => Environment.default) + + ent = Enterprise.create!(:name => 'test enterprise 1', :identifier => 'test_ent1', :category_ids => [@category.id]) + p1 = ent.products.create!(:name => 'test product 1', :product_category => pc1) + p2 = ent.products.create!(:name => 'test product 2', :product_category => pc11) + p3 = ent.products.create!(:name => 'test product 3', :product_category => pc2) + p4 = ent.products.create!(:name => 'test product 4', :product_category => pc2) # not in the count + p5 = ent.products.create!(:name => 'test product 5', :product_category => pc3) # not in the count + + ent2 = Enterprise.create!(:name => 'test enterprise 2', :identifier => 'test_ent2') + p6 = ent2.products.create!(:name => 'test product 6', :product_category => pc1) + + counts = @finder.product_categories_count(:products, [pc1.id, pc11.id, pc2.id], [p1.id, p2.id, p3.id, p5.id, p6.id] ) + + assert_equal 2, counts[pc1.id] + assert_equal 1, counts[pc11.id] + assert_equal 1, counts[pc2.id] + assert_nil counts[pc3.id] + end + + should 'count product categories results by all products' do + pc1 = ProductCategory.create!(:name => 'test cat1', :environment => Environment.default) + pc11 = ProductCategory.create!(:name => 'test cat11', :environment => Environment.default, :parent => pc1) + pc2 = ProductCategory.create!(:name => 'test cat2', :environment => Environment.default) + pc3 = ProductCategory.create!(:name => 'test cat3', :environment => Environment.default) + + ent = Enterprise.create!(:name => 'test enterprise 1', :identifier => 'test_ent1', :category_ids => [@category.id]) + p1 = ent.products.create!(:name => 'test product 1', :product_category => pc1) + p2 = ent.products.create!(:name => 'test product 2', :product_category => pc11) + p3 = ent.products.create!(:name => 'test product 3', :product_category => pc2) + p4 = ent.products.create!(:name => 'test product 4', :product_category => pc3) # not in the count + + ent2 = Enterprise.create!(:name => 'test enterprise 2', :identifier => 'test_ent2') + p6 = ent2.products.create!(:name => 'test product 6', :product_category => pc1) + + + counts = @finder.product_categories_count(:products, [pc1.id, pc11.id, pc2.id] ) + + assert_equal 2, counts[pc1.id] + assert_equal 1, counts[pc11.id] + assert_equal 1, counts[pc2.id] + assert_nil counts[pc3.id] + end + + should 'count product categories results by enterprises' do + pc1 = ProductCategory.create!(:name => 'test cat1', :environment => Environment.default) + pc11 = ProductCategory.create!(:name => 'test cat11', :environment => Environment.default, :parent => pc1) + pc2 = ProductCategory.create!(:name => 'test cat2', :environment => Environment.default) + pc3 = ProductCategory.create!(:name => 'test cat3', :environment => Environment.default) + + ent1 = Enterprise.create!(:name => 'test enterprise 1', :identifier => 'test_ent1', :category_ids => [@category.id]) + ent1.products.create!(:name => 'test product 1', :product_category => pc1) + ent1.products.create!(:name => 'test product 2', :product_category => pc1) + ent2 = Enterprise.create!(:name => 'test enterprise 2', :identifier => 'test_ent2', :category_ids => [@category.id]) + ent2.products.create!(:name => 'test product 2', :product_category => pc11) + ent3 = Enterprise.create!(:name => 'test enterprise 3', :identifier => 'test_ent3', :category_ids => [@category.id]) + ent3.products.create!(:name => 'test product 3', :product_category => pc2) + ent4 = Enterprise.create!(:name => 'test enterprise 4', :identifier => 'test_ent4', :category_ids => [@category.id]) + ent4.products.create!(:name => 'test product 4', :product_category => pc2) + ent5 = Enterprise.create!(:name => 'test enterprise 5', :identifier => 'test_ent5', :category_ids => [@category.id]) + ent5.products.create!(:name => 'test product 5', :product_category => pc2) + ent5.products.create!(:name => 'test product 6', :product_category => pc3) + + ent6 = Enterprise.create!(:name => 'test enterprise 6', :identifier => 'test_ent6') + p6 = ent2.products.create!(:name => 'test product 6', :product_category => pc1) + + counts = @finder.product_categories_count(:enterprises, [pc1.id, pc11.id, pc2.id], [ent1.id, ent2.id, ent3.id, ent4.id] ) + + assert_equal 2, counts[pc1.id] + assert_equal 1, counts[pc11.id] + assert_equal 2, counts[pc2.id] + assert_nil counts[pc3.id] + end + + should 'count product categories results by all enterprises' do + pc1 = ProductCategory.create!(:name => 'test cat1', :environment => Environment.default) + pc11 = ProductCategory.create!(:name => 'test cat11', :environment => Environment.default, :parent => pc1) + pc2 = ProductCategory.create!(:name => 'test cat2', :environment => Environment.default) + pc3 = ProductCategory.create!(:name => 'test cat3', :environment => Environment.default) + + ent1 = Enterprise.create!(:name => 'test enterprise 1', :identifier => 'test_ent1', :category_ids => [@category.id]) + ent1.products.create!(:name => 'test product 1', :product_category => pc1) + ent1.products.create!(:name => 'test product 2', :product_category => pc1) + ent2 = Enterprise.create!(:name => 'test enterprise 2', :identifier => 'test_ent2', :category_ids => [@category.id]) + ent2.products.create!(:name => 'test product 2', :product_category => pc11) + ent3 = Enterprise.create!(:name => 'test enterprise 3', :identifier => 'test_ent3', :category_ids => [@category.id]) + ent3.products.create!(:name => 'test product 3', :product_category => pc2) + ent4 = Enterprise.create!(:name => 'test enterprise 4', :identifier => 'test_ent4', :category_ids => [@category.id]) + ent4.products.create!(:name => 'test product 4', :product_category => pc2) + ent4.products.create!(:name => 'test product 5', :product_category => pc3) + + ent5 = Enterprise.create!(:name => 'test enterprise 5', :identifier => 'test_ent5') + p6 = ent2.products.create!(:name => 'test product 6', :product_category => pc1) + + counts = @finder.product_categories_count(:enterprises, [pc1.id, pc11.id, pc2.id] ) + + assert_equal 2, counts[pc1.id] + assert_equal 1, counts[pc11.id] + assert_equal 2, counts[pc2.id] + assert_nil counts[pc3.id] + end + end -- libgit2 0.21.2