diff --git a/spec/counter_culture_spec.rb b/spec/counter_culture_spec.rb index 31a67eb..035a0a2 100644 --- a/spec/counter_culture_spec.rb +++ b/spec/counter_culture_spec.rb @@ -34,6 +34,9 @@ require 'models/group' require 'models/sub_group' require 'models/group_item' +require 'models/habtm_product' +require 'models/habtm_category' +require 'models/habtm_category_product' if ENV['DB'] == 'postgresql' require 'models/purchase_order' @@ -2766,4 +2769,118 @@ def mess_up_counts po.reload expect(po.total_amount).to eq(0.0) end + + context 'has_and_belongs_to_many' do + let(:create_ar_categories!) do + HabtmCategory.create(name: 'Category') + HabtmCategory.create(name: 'New Category') + HabtmCategory.create(name: 'Another new Category') + end + + let(:create_ar_product!) do + HabtmProduct.create(name: 'Visible Product', visible: true) + HabtmProduct.create(name: 'Hidden / Invisible Product', visible: false) + end + + before :each do + HabtmCategoriesProduct.destroy_all + HabtmCategory.destroy_all + HabtmProduct.destroy_all + create_ar_product! + create_ar_categories! + end + + let(:product) { HabtmProduct.first } + let(:hidden_product) { HabtmProduct.last } + let(:category) { HabtmCategory.first } + let(:new_category) { HabtmCategory.all[1] } + let(:another_new_category) { HabtmCategory.all[2] } + + describe 'functional test' do + it 'assigns product to category through <<' do + product.habtm_categories << category + expect(HabtmCategory.find(category.id).habtm_products).to include(product) + end + + it 'assigns product to category through update' do + product.update!(habtm_categories: [category]) + expect(HabtmCategory.find(category.id).habtm_products).to include(product) + end + + it 'deletes product from category through update' do + product.update!(habtm_categories: [category]) + product.update!(habtm_categories: [new_category]) + expect(HabtmCategory.find(category.id).habtm_products).to_not include(product) + expect(HabtmCategory.find(new_category.id).habtm_products).to include(product) + end + + it 'deletes properly' do + product.habtm_categories << category + product.habtm_categories.destroy(product.habtm_categories.last) + expect(category.reload.products_count).to eql 0 + end + + it 'count products' do + product.habtm_categories << category + + expect(category.reload.habtm_products.count).to eql 1 + end + end + + describe 'adding' do + it 'via "<<" counts up' do + product.habtm_categories << category + expect(category.reload.products_count).to eql 1 + end + + it 'via "update" counts up' do + product.update(habtm_categories: [category]) + expect(category.reload.products_count).to eql 1 + end + + it 'via "update" counts up (sanity check)' do + product.update(habtm_categories: [category]) + product.update(habtm_categories: [new_category, another_new_category]) + expect(category.reload.habtm_products.count).to eql 0 + expect(new_category.reload.habtm_products.count).to eql 1 + expect(another_new_category.reload.habtm_products.count).to eql 1 + end + end + + context 'update' do + before :each do + product.update(habtm_categories: [new_category]) + end + + it 'removes from the old category' do + expect(category.reload.products_count).to eql 0 + end + + it 'adds to the new category' do + expect(new_category.reload.products_count).to eql 1 + end + end + + context '<<' do + before :each do + product.habtm_categories << new_category + end + + it 'adds to the new category' do + expect(new_category.reload.products_count).to eql 1 + end + + it 'removes from the old category' do + category.habtm_products.destroy(product) + expect(category.reload.products_count).to eql 0 + expect(new_category.reload.products_count).to eql 1 + end + end + + it 'removes old relation via "update"' do + product.update(habtm_categories: [category]) + product.update(habtm_categories: [new_category, another_new_category]) + expect(category.reload.products_count).to eql 0 + end + end end diff --git a/spec/models/habtm_category.rb b/spec/models/habtm_category.rb new file mode 100644 index 0000000..66da2a7 --- /dev/null +++ b/spec/models/habtm_category.rb @@ -0,0 +1,4 @@ +class HabtmCategory < ActiveRecord::Base + has_many :habtm_categories_products + has_many :habtm_products, through: :habtm_categories_products, class_name: 'HabtmProduct' +end \ No newline at end of file diff --git a/spec/models/habtm_category_product.rb b/spec/models/habtm_category_product.rb new file mode 100644 index 0000000..3285610 --- /dev/null +++ b/spec/models/habtm_category_product.rb @@ -0,0 +1,11 @@ +class HabtmCategoriesProduct < ActiveRecord::Base + belongs_to :habtm_product + belongs_to :habtm_category + + counter_culture :habtm_category, + column_name: ->(model) { model.habtm_product.visible? ? 'products_count' : nil }, + column_names: { + HabtmProduct.visible => 'products_count' + }, + touch: true +end \ No newline at end of file diff --git a/spec/models/habtm_product.rb b/spec/models/habtm_product.rb new file mode 100644 index 0000000..9dc3e77 --- /dev/null +++ b/spec/models/habtm_product.rb @@ -0,0 +1,7 @@ +class HabtmProduct < ActiveRecord::Base + has_many :habtm_categories_products, dependent: :destroy + has_many :habtm_categories, through: :habtm_categories_products, class_name: 'HabtmCategory' + + scope :visible, -> { where(visible: true) } # to be able to mix with conditional counts + +end \ No newline at end of file diff --git a/spec/schema.rb b/spec/schema.rb index 59d3139..ae6f5e8 100644 --- a/spec/schema.rb +++ b/spec/schema.rb @@ -225,6 +225,21 @@ t.integer "special_poly_images_count", :default => 0, :null => false end + create_table "habtm_products", :force => true do |t| + t.string "name", :null => false + t.boolean "visible", default: false + end + + create_table "habtm_categories", :force => true do |t| + t.string "name", :null => false + t.integer "products_count", default: 0, null: false + end + + create_table "habtm_categories_products", :force => true do |t| + t.integer "habtm_category_id", :null => false + t.integer "habtm_product_id", :null => false + end + create_table "conversations", :force => true do |t| t.integer "candidate_id" end