From fafc7edd0b4786f839e664623d6de4cd31d5cfcc Mon Sep 17 00:00:00 2001 From: MoisesMachado Date: Thu, 10 Jul 2008 21:05:30 +0000 Subject: [PATCH] ActionItem514: change products categorization to sync with a join table for peformance --- app/models/product.rb | 9 +++++++++ app/models/product_categorization.rb | 13 +++++++++++++ db/migrate/044_create_product_categorizations.rb | 22 ++++++++++++++++++++++ db/migrate/044_update_regions_to_become_states_and_cities.rb | 11 ----------- db/schema.rb | 12 ++++++++++-- test/unit/product_categorization_test.rb | 8 ++++++++ test/unit/product_test.rb | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 app/models/product_categorization.rb create mode 100644 db/migrate/044_create_product_categorizations.rb delete mode 100644 db/migrate/044_update_regions_to_become_states_and_cities.rb create mode 100644 test/unit/product_categorization_test.rb diff --git a/app/models/product.rb b/app/models/product.rb index fb6bcbc..dadfe7f 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -19,6 +19,15 @@ class Product < ActiveRecord::Base p.enterprise.product_updated if p.enterprise end + after_save do |p| + if (p.product_category && !ProductCategorization.find(:first, :conditions => {:category_id => p.product_category.id, :product_id => p.id})) || (!p.product_category) + ProductCategorization.remove_all_for(p) + if p.product_category + ProductCategorization.add_category_to_product(p.product_category, p) + end + end + end + acts_as_searchable :fields => [ :name, :description, :category_full_name ] xss_terminate :only => [ :name, :description ] diff --git a/app/models/product_categorization.rb b/app/models/product_categorization.rb new file mode 100644 index 0000000..3185b3e --- /dev/null +++ b/app/models/product_categorization.rb @@ -0,0 +1,13 @@ +class ProductCategorization < ActiveRecord::Base + belongs_to :product_category, :foreign_key => 'category_id' + belongs_to :product + + extend Categorization + + class << self + alias :add_category_to_product :add_category_to_object + def object_id_column + :product_id + end + end +end diff --git a/db/migrate/044_create_product_categorizations.rb b/db/migrate/044_create_product_categorizations.rb new file mode 100644 index 0000000..86cec22 --- /dev/null +++ b/db/migrate/044_create_product_categorizations.rb @@ -0,0 +1,22 @@ +class CreateProductCategorizations < ActiveRecord::Migration + def self.up + + create_table :product_categorizations do |t| + t.integer :category_id + t.integer :product_id + t.boolean :virtual, :default => false + + t.timestamps + end + +# FIXME:uncomment after implementation +# Product.find(:all).each do |p| +# ProductCategorization.add_category_to_product(p.product_category, p) +# end + + end + + def self.down + drop_table :product_categorizations + end +end diff --git a/db/migrate/044_update_regions_to_become_states_and_cities.rb b/db/migrate/044_update_regions_to_become_states_and_cities.rb deleted file mode 100644 index 5cb96e7..0000000 --- a/db/migrate/044_update_regions_to_become_states_and_cities.rb +++ /dev/null @@ -1,11 +0,0 @@ -class UpdateRegionsToBecomeStatesAndCities < ActiveRecord::Migration - def self.up - execute "update categories set type = 'State' where parent_id in (select id from categories where type = 'Region' and parent_id in (select id from categories where type = 'Region' and name = 'Nacional'))" - - execute "update categories set type = 'City' where parent_id in (select id from categories where type = 'State')" - end - - def self.down - execute "update categories set type = 'Region' where type = 'State' or type = 'City'" - end -end diff --git a/db/schema.rb b/db/schema.rb index bf7e7a1..955bfc4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -71,8 +71,8 @@ ActiveRecord::Schema.define(:version => 45) do t.boolean "virtual", :default => false end - add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id" add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" + add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id" create_table "blocks", :force => true do |t| t.string "title" @@ -162,6 +162,14 @@ ActiveRecord::Schema.define(:version => 45) do t.integer "height" end + create_table "product_categorizations", :force => true do |t| + t.integer "category_id" + t.integer "product_id" + t.boolean "virtual", :default => false + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "products", :force => true do |t| t.integer "enterprise_id" t.integer "product_category_id" @@ -222,8 +230,8 @@ ActiveRecord::Schema.define(:version => 45) do t.datetime "created_at" end - add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" create_table "tags", :force => true do |t| t.string "name" diff --git a/test/unit/product_categorization_test.rb b/test/unit/product_categorization_test.rb new file mode 100644 index 0000000..64f6c13 --- /dev/null +++ b/test/unit/product_categorization_test.rb @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class ProductCategorizationTest < ActiveSupport::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/test/unit/product_test.rb b/test/unit/product_test.rb index 163cb65..1ccf2f9 100644 --- a/test/unit/product_test.rb +++ b/test/unit/product_test.rb @@ -122,4 +122,50 @@ class ProductTest < Test::Unit::TestCase assert_same result, product.url end + should 'categorize also with product categorization' do + cat = ProductCategory.create(:name => 'test cat', :environment => Environment.default) + ent = Enterprise.create!(:name => 'test ent', :identifier => 'test_ent') + p = ent.products.create!(:name => 'test product') + p.product_category = cat + p.save! + + assert ProductCategorization.find(:first, :conditions => {:product_id => p, :category_id => cat}) + end + + should 'categorize parent cateogries with product categorization' do + parent_cat = ProductCategory.create(:name => 'test cat', :environment => Environment.default) + child_cat = ProductCategory.create(:name => 'test cat', :environment => Environment.default, :parent => parent_cat) + ent = Enterprise.create!(:name => 'test ent', :identifier => 'test_ent') + p = ent.products.create!(:name => 'test product') + p.product_category = child_cat + p.save! + + assert ProductCategorization.find(:first, :conditions => {:product_id => p, :category_id => parent_cat}) + assert ProductCategorization.find(:first, :conditions => {:product_id => p, :category_id => child_cat}) + end + + should 'change product categorization when product category changes' do + cat1 = ProductCategory.create(:name => 'test cat 1', :environment => Environment.default) + cat2 = ProductCategory.create(:name => 'test cat 2', :environment => Environment.default) + ent = Enterprise.create!(:name => 'test ent', :identifier => 'test_ent') + p = ent.products.create!(:name => 'test product', :product_category => cat1) + + p.product_category = cat2 + p.save! + + assert ProductCategorization.find(:first, :conditions => {:product_id => p, :category_id => cat2}), 'must include the new category' + assert !ProductCategorization.find(:first, :conditions => {:product_id => p, :category_id => cat1}), 'must exclude the old category' + end + + should 'remove categorization when product category is removed' do + cat = ProductCategory.create(:name => 'test cat', :environment => Environment.default) + ent = Enterprise.create!(:name => 'test ent', :identifier => 'test_ent') + p = ent.products.create!(:name => 'test product', :product_category => cat) + + p.product_category = nil + p.save! + + assert !ProductCategorization.find(:first, :conditions => {:product_id => p, :category_id => cat}) + end + end -- libgit2 0.21.2