From ea8d189d6c6422352c6dc1995f194088fd6e3419 Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Tue, 28 May 2019 19:37:53 +0800 Subject: [PATCH] Bulk update OC variant changes in OC form --- app/services/exchange_variant_bulk_updater.rb | 36 ++++++++++++++++ .../order_cycle_form_applicator.rb | 8 ++++ .../exchange_variant_bulk_updater_spec.rb | 43 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 app/services/exchange_variant_bulk_updater.rb create mode 100644 spec/services/exchange_variant_bulk_updater_spec.rb diff --git a/app/services/exchange_variant_bulk_updater.rb b/app/services/exchange_variant_bulk_updater.rb new file mode 100644 index 0000000000..330425852e --- /dev/null +++ b/app/services/exchange_variant_bulk_updater.rb @@ -0,0 +1,36 @@ +class ExchangeVariantBulkUpdater + def initialize(exchange) + @exchange = exchange + end + + def update!(variant_ids) + sanitized_variant_ids = variant_ids.map(&:to_i).uniq + existing_variant_ids = @exchange.variant_ids + + disassociate_variants!(existing_variant_ids - sanitized_variant_ids) + associate_variants!(sanitized_variant_ids - existing_variant_ids) + + uncache_variant_associations + end + + private + + def disassociate_variants!(variant_ids) + return if variant_ids.blank? + @exchange.exchange_variants.where(variant_id: variant_ids).delete_all + end + + def associate_variants!(variant_ids) + return if variant_ids.blank? + + new_exchange_variants = variant_ids.map do |variant_id| + ExchangeVariant.new(exchange_id: @exchange.id, variant_id: variant_id) + end + ExchangeVariant.import!(new_exchange_variants) + end + + def uncache_variant_associations + @exchange.exchange_variants.reset + @exchange.variants.proxy_association.reset + end +end diff --git a/lib/open_food_network/order_cycle_form_applicator.rb b/lib/open_food_network/order_cycle_form_applicator.rb index a5bec43bef..ba177bcc28 100644 --- a/lib/open_food_network/order_cycle_form_applicator.rb +++ b/lib/open_food_network/order_cycle_form_applicator.rb @@ -66,10 +66,13 @@ module OpenFoodNetwork def add_exchange(sender_id, receiver_id, incoming, attrs = {}) attrs = attrs.reverse_merge(sender_id: sender_id, receiver_id: receiver_id, incoming: incoming) + variant_ids = attrs.delete :variant_ids exchange = @order_cycle.exchanges.build attrs if manages_coordinator? exchange.save! + ExchangeVariantBulkUpdater.new(exchange).update!(variant_ids) unless variant_ids.nil? + @touched_exchanges << exchange end end @@ -85,7 +88,12 @@ module OpenFoodNetwork end if permission_for exchange + variant_ids = attrs.delete :variant_ids + exchange.update_attributes!(attrs) + + ExchangeVariantBulkUpdater.new(exchange).update!(variant_ids) unless variant_ids.nil? + @touched_exchanges << exchange end end diff --git a/spec/services/exchange_variant_bulk_updater_spec.rb b/spec/services/exchange_variant_bulk_updater_spec.rb new file mode 100644 index 0000000000..2b575ae51c --- /dev/null +++ b/spec/services/exchange_variant_bulk_updater_spec.rb @@ -0,0 +1,43 @@ +require "spec_helper" + +describe ExchangeVariantBulkUpdater do + let!(:first_variant) { create(:variant) } + let!(:second_variant) { create(:variant) } + let!(:third_variant) { create(:variant) } + + it "associates new variants to the exchange" do + exchange = create(:exchange) + + described_class.new(exchange).update!([first_variant.id, second_variant.id]) + + # Check association cache. + expect(exchange.variants).to include(first_variant) + expect(exchange.variants).to include(second_variant) + # Check if changes are actually persisted. + exchange.reload + expect(exchange.variants).to include(first_variant) + expect(exchange.variants).to include(second_variant) + end + + it "disassociates variants from the exchange" do + exchange = create(:exchange, variant_ids: [first_variant.id, second_variant.id]) + + described_class.new(exchange).update!([first_variant.id, third_variant.id]) + + # Check association cache. + expect(exchange.variants).to include(first_variant) + expect(exchange.variants).to include(third_variant) + # Check if changes are actually persisted. + exchange.reload + expect(exchange.variants).to include(first_variant) + expect(exchange.variants).to include(third_variant) + + described_class.new(exchange).update!([]) + + # Check association cache. + expect(exchange.variants).to be_blank + # Check if changes are actually persisted. + exchange.reload + expect(exchange.variants).to be_blank + end +end