From 93cb845ee2ecc37f1a2024495e8d1a686ca6c847 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 17 Oct 2013 11:15:43 +1100 Subject: [PATCH] DB and model changes to make ShippingMethod distributor habtm --- app/models/spree/shipping_method_decorator.rb | 11 ++---- ..._shipping_methods_distributors_to_habtm.rb | 37 +++++++++++++++++++ db/schema.rb | 15 +++++--- spec/factories.rb | 4 +- spec/models/spree/shipping_method_spec.rb | 25 +++++++++++-- 5 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb diff --git a/app/models/spree/shipping_method_decorator.rb b/app/models/spree/shipping_method_decorator.rb index 49f333b790..dd8ec43c87 100644 --- a/app/models/spree/shipping_method_decorator.rb +++ b/app/models/spree/shipping_method_decorator.rb @@ -1,23 +1,20 @@ Spree::ShippingMethod.class_eval do - belongs_to :distributor, class_name: 'Enterprise' - attr_accessible :distributor_id - - validates_presence_of :distributor_id + has_and_belongs_to_many :distributors, join_table: 'distributors_shipping_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id' + attr_accessible :distributor_ids scope :by_distributor, lambda { - joins(:distributor). + joins(:distributors). order('enterprises.name, spree_shipping_methods.name'). select('enterprises.*, spree_shipping_methods.*') } def available_to_order_with_distributor_check?(order, display_on=nil) available_to_order_without_distributor_check?(order, display_on) && - (order.distributor == self.distributor) + self.distributors.include?(order.distributor) end alias_method_chain :available_to_order?, :distributor_check def adjustment_label 'Delivery' end - end diff --git a/db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb b/db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb new file mode 100644 index 0000000000..8d26c88d9b --- /dev/null +++ b/db/migrate/20131016230055_convert_shipping_methods_distributors_to_habtm.rb @@ -0,0 +1,37 @@ +class ConvertShippingMethodsDistributorsToHabtm < ActiveRecord::Migration + class Spree::ShippingMethod < ActiveRecord::Base + belongs_to :distributor, class_name: 'Enterprise' + has_and_belongs_to_many :distributors, join_table: 'distributors_shipping_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id' + end + + def up + create_table :distributors_shipping_methods, id: false do |t| + t.references :distributor + t.references :shipping_method + end + add_index :distributors_shipping_methods, :distributor_id + add_index :distributors_shipping_methods, :shipping_method_id + + Spree::ShippingMethod.all.each do |sm| + sm.distributors << sm.distributor if sm.distributor_id + end + + remove_column :spree_shipping_methods, :distributor_id + end + + def down + add_column :spree_shipping_methods, :distributor_id, :integer + add_index :spree_shipping_methods, :distributor_id + + Spree::ShippingMethod.all.each do |sm| + if sm.distributors.present? + sm.distributor = sm.distributors.first + sm.save! + + say "WARNING: Discarding #{sm.distributors.count-1} distributors while flattening HABTM relation to belongs_to" if sm.distributors.count > 1 + end + end + + drop_table :distributors_shipping_methods + end +end diff --git a/db/schema.rb b/db/schema.rb index 517b5eb6ca..c8b8eac480 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130919010513) do +ActiveRecord::Schema.define(:version => 20131016230055) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -154,6 +154,14 @@ ActiveRecord::Schema.define(:version => 20130919010513) do t.integer "payment_method_id" end + create_table "distributors_shipping_methods", :id => false, :force => true do |t| + t.integer "distributor_id" + t.integer "shipping_method_id" + end + + add_index "distributors_shipping_methods", ["distributor_id"], :name => "index_distributors_shipping_methods_on_distributor_id" + add_index "distributors_shipping_methods", ["shipping_method_id"], :name => "index_distributors_shipping_methods_on_shipping_method_id" + create_table "enterprise_fees", :force => true do |t| t.integer "enterprise_id" t.string "fee_type" @@ -462,9 +470,9 @@ ActiveRecord::Schema.define(:version => 20130919010513) do t.string "email" t.text "special_instructions" t.integer "distributor_id" + t.integer "order_cycle_id" t.string "currency" t.string "last_ip_address" - t.integer "order_cycle_id" t.integer "cart_id" end @@ -721,11 +729,8 @@ ActiveRecord::Schema.define(:version => 20130919010513) do t.boolean "match_all" t.boolean "match_one" t.datetime "deleted_at" - t.integer "distributor_id" end - add_index "spree_shipping_methods", ["distributor_id"], :name => "index_spree_shipping_methods_on_distributor_id" - create_table "spree_skrill_transactions", :force => true do |t| t.string "email" t.float "amount" diff --git a/spec/factories.rb b/spec/factories.rb index 755d69d9c4..1c27a8c916 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -151,7 +151,7 @@ FactoryGirl.modify do end factory :shipping_method do - distributor { Enterprise.is_distributor.first || FactoryGirl.create(:distributor_enterprise) } + distributors { [Enterprise.is_distributor.first || FactoryGirl.create(:distributor_enterprise)] } display_on '' end @@ -168,7 +168,7 @@ FactoryGirl.modify do end factory :payment_method do - distributors { [Enterprise.is_distributor.first || FactoryGirl.create(:distributor_enterprise)] } #Always need a distributor + distributors { [Enterprise.is_distributor.first || FactoryGirl.create(:distributor_enterprise)] } end end diff --git a/spec/models/spree/shipping_method_spec.rb b/spec/models/spree/shipping_method_spec.rb index d147358907..21b0f5e953 100644 --- a/spec/models/spree/shipping_method_spec.rb +++ b/spec/models/spree/shipping_method_spec.rb @@ -6,15 +6,34 @@ module Spree build(:shipping_method).should be_valid end - it "requires a distributor" do - build(:shipping_method, distributor: nil).should_not be_valid + it "can have distributors" do + d1 = create(:distributor_enterprise) + d2 = create(:distributor_enterprise) + sm = create(:shipping_method) + + sm.distributors.clear + sm.distributors << d1 + sm.distributors << d2 + + sm.reload.distributors.should == [d1, d2] + end + + it "can order by distributor" do + d1 = create(:distributor_enterprise, name: '222') + d2 = create(:distributor_enterprise, name: '111') + + sm1 = create(:shipping_method, distributors: [d2], name: 'ZZ') + sm2 = create(:shipping_method, distributors: [d1], name: 'BB') + sm3 = create(:shipping_method, distributors: [d1], name: 'AA') + + ShippingMethod.by_distributor.should == [sm1, sm3, sm2] end describe "availability" do let(:sm) { build(:shipping_method) } it "is available to orders that match its distributor" do - o = build(:order, ship_address: build(:address), distributor: sm.distributor) + o = build(:order, ship_address: build(:address), distributor: sm.distributors.first) sm.should be_available_to_order o end