Skip to content

Commit 7db69a4

Browse files
authored
Merge pull request #4954 from coalest/refactor-total-item-calculations-for-performance
Perf: Refactor total items calculations
2 parents bf2dfa8 + b8d9fe2 commit 7db69a4

File tree

9 files changed

+49
-18
lines changed

9 files changed

+49
-18
lines changed

app/controllers/manufacturers_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class ManufacturersController < ApplicationController
22
def index
3-
@manufacturers = current_organization.manufacturers.includes(:donations).all.alphabetized
3+
@manufacturers = current_organization.manufacturers.with_volumes.alphabetized
44
end
55

66
def create

app/controllers/product_drive_participants_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class ProductDriveParticipantsController < ApplicationController
66
# TODO: Should there be a :destroy action for this?
77

88
def index
9-
@product_drive_participants = current_organization.product_drive_participants.includes(:donations).all.order(:business_name)
9+
@product_drive_participants = current_organization.product_drive_participants.with_volumes.order(:business_name)
1010

1111
respond_to do |format|
1212
format.html

app/controllers/vendors_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class VendorsController < ApplicationController
33
include Importable
44

55
def index
6-
@vendors = current_organization.vendors.includes(:purchases).all.alphabetized
6+
@vendors = current_organization.vendors.with_volumes.alphabetized
77

88
respond_to do |format|
99
format.html

app/models/manufacturer.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ class Manufacturer < ApplicationRecord
2121

2222
scope :alphabetized, -> { order(:name) }
2323

24-
def volume
25-
# returns 0 instead of nil when Manufacturer exists without any donations
26-
donations.joins(:line_items).sum(:quantity)
27-
end
24+
scope :with_volumes, -> {
25+
left_joins(donations: :line_items)
26+
.select("manufacturers.*, SUM(COALESCE(line_items.quantity, 0)) AS volume")
27+
.group(:id)
28+
}
2829

2930
def self.by_donation_date(count = 10, date_range = nil)
3031
# selects manufacturers that have donation qty > 0 in the provided date range

app/models/product_drive_participant.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ class ProductDriveParticipant < ApplicationRecord
3030
validates :comment, length: { maximum: 500 }
3131

3232
scope :alphabetized, -> { order(:contact_name) }
33+
scope :with_volumes, -> {
34+
left_joins(donations: :line_items)
35+
.select("product_drive_participants.*, SUM(COALESCE(line_items.quantity, 0)) AS volume")
36+
.group(:id)
37+
}
3338

3439
def volume
3540
donations.map { |d| d.line_items.total }.reduce(:+)

app/models/vendor.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ class Vendor < ApplicationRecord
2727

2828
scope :alphabetized, -> { order(:business_name) }
2929

30-
def volume
31-
purchases.map { |d| d.line_items.total }.reduce(:+)
32-
end
30+
scope :with_volumes, -> {
31+
left_joins(purchases: :line_items)
32+
.select("vendors.*, SUM(COALESCE(line_items.quantity, 0)) AS volume")
33+
.group(:id)
34+
}
3335
end

spec/models/manufacturer_spec.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,37 @@
2323
end
2424
end
2525

26-
context "Methods" do
27-
describe "volume" do
26+
context "Scopes" do
27+
describe "with_volumes" do
28+
subject { described_class.with_volumes }
29+
2830
it "retrieves the amount of product that has been donated by manufacturer" do
2931
mfg = create(:manufacturer)
3032
create(:donation, :with_items, item_quantity: 15, source: Donation::SOURCES[:manufacturer], manufacturer: mfg)
31-
expect(mfg.volume).to eq(15)
33+
34+
expect(subject.first.volume).to eq(15)
3235
end
3336

3437
it "retrieves the amount of product that has been donated by manufacturer from multiple donations" do
3538
mfg = create(:manufacturer)
3639
create(:donation, :with_items, item_quantity: 15, source: Donation::SOURCES[:manufacturer], manufacturer: mfg)
3740
create(:donation, :with_items, item_quantity: 10, source: Donation::SOURCES[:manufacturer], manufacturer: mfg)
38-
expect(mfg.volume).to eq(25)
41+
42+
expect(subject.first.volume).to eq(25)
3943
end
4044

4145
it "ignores the amount of product from other manufacturers" do
4246
mfg = create(:manufacturer)
4347
mfg2 = create(:manufacturer)
4448
create(:donation, :with_items, item_quantity: 5, source: Donation::SOURCES[:manufacturer], manufacturer: mfg)
4549
create(:donation, :with_items, item_quantity: 10, source: Donation::SOURCES[:manufacturer], manufacturer: mfg2)
46-
expect(mfg.volume).to eq(5)
50+
51+
expect(subject.first.volume).to eq(5)
4752
end
4853
end
54+
end
4955

56+
context "Methods" do
5057
describe "by_donation_date" do
5158
before do
5259
# Prepare manufacturers with donations for tests

spec/models/product_drive_participant_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@
3838
end
3939
end
4040

41+
context "Scopes" do
42+
describe "with_volumes" do
43+
subject { described_class.with_volumes }
44+
it "retrieves the amount of product that has been donated by participant" do
45+
dd = create(:product_drive)
46+
ddp = create(:product_drive_participant)
47+
create(:donation, :with_items, item_quantity: 10, source: Donation::SOURCES[:product_drive], product_drive: dd, product_drive_participant: ddp)
48+
49+
expect(subject.first.volume).to eq(10)
50+
end
51+
end
52+
end
53+
4154
context "Methods" do
4255
describe "volume" do
4356
it "retrieves the amount of product that has been donated by participant" do

spec/models/vendor_spec.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,15 @@
2626
end
2727
end
2828

29-
context "Methods" do
30-
describe "volume" do
29+
context "Scopes" do
30+
describe "with_volumes" do
31+
subject { described_class.with_volumes }
32+
3133
it "retrieves the amount of product that has been bought from this vendor" do
3234
vendor = create(:vendor)
3335
create(:purchase, :with_items, item_quantity: 10, amount_spent_in_cents: 1, vendor: vendor)
34-
expect(vendor.volume).to eq(10)
36+
37+
expect(subject.first.volume).to eq(10)
3538
end
3639
end
3740
end

0 commit comments

Comments
 (0)