Skip to content

Commit

Permalink
Perf: Refactor ProductDrive#index with service
Browse files Browse the repository at this point in the history
  • Loading branch information
coalest committed Dec 21, 2024
1 parent 456588a commit 596f5a6
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 deletions.
6 changes: 5 additions & 1 deletion app/controllers/product_drives_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ def index
setup_date_range_picker
@product_drives = current_organization
.product_drives
.includes(donations: {line_items: :item})
.class_filter(filter_params)
.within_date_range(@selected_date_range)
.order(start_date: :desc)
Expand All @@ -15,6 +14,11 @@ def index
@item_categories = current_organization.item_categories
@selected_name_filter = filter_params[:by_name]
@selected_item_category = filter_params[:by_item_category_id]
@summary = ProductDriveSummaryService.new(
product_drives: @product_drives,
within_date_range: @selected_date_range,
item_category_id: @selected_item_category
).call

respond_to do |format|
format.html
Expand Down
2 changes: 1 addition & 1 deletion app/models/product_drive.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ProductDrive < ApplicationRecord

scope :by_name, ->(name_filter) { where(name: name_filter) }
scope :by_item_category_id, ->(item_category_id) {
joins(donations: {line_items: :item})
includes(donations: {line_items: :item})
.where(item: { item_category_id: item_category_id })
}

Expand Down
52 changes: 52 additions & 0 deletions app/services/product_drive_summary_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
class ProductDriveSummaryService
def initialize(product_drives:, within_date_range:, item_category_id:)
@product_drives = product_drives
@within_date_range = within_date_range
@item_category_id = item_category_id
end

def call
calculate_summary
self
end

def fetch_quantity(product_drive_id)
@summary.dig(product_drive_id, :quantity)
end

def fetch_unique_item_count(product_drive_id)
@summary.dig(product_drive_id, :unique_item_count)
end

def fetch_value(product_drive_id)
@summary.dig(product_drive_id, :value)
end

private

# Returns hash of total quantity, unique item count and value per product drive
# Example return: { 1 => { quantity: 15, unique_item_count: 2, value: 100 }, ...}
#
# @return [Hash<Hash<Symbol, Integer>>]
def calculate_summary
@summary ||= begin
query = ProductDrive
.left_joins(donations: {line_items: [:item]})
.where(id: @product_drives.ids)
.within_date_range(@within_date_range)
.group("product_drives.id")
.distinct

query = query.where(items: {item_category_id: @item_category_id}) if @item_category_id.present?

query.pluck(Arel.sql(
"product_drives.id AS id,
COALESCE(SUM(line_items.quantity), 0) AS quantity,
COUNT(DISTINCT line_items.item_id) AS unique_item_count,
COALESCE(SUM(COALESCE(items.value_in_cents, 0) * line_items.quantity), 0) AS value"
)).to_h do |(id, quantity, unique_item_count, value)|
[id, {quantity:, unique_item_count:, value:}]
end
end
end
end
6 changes: 3 additions & 3 deletions app/views/product_drives/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@
<td><%= product_drive.start_date.strftime("%m-%d-%Y") %></td>
<td><%= product_drive.end_date&.strftime("%m-%d-%Y") %></td>
<td><%= is_virtual(product_drive: product_drive) %></td>
<td class="text-right"><%= product_drive.donation_quantity_by_date(selected_range, @selected_item_category) %></td>
<td class="text-right"><%= product_drive.distinct_items_count_by_date(selected_range, @selected_item_category) %></td>
<td class="text-right"><strong><%= dollar_value(product_drive.in_kind_value) %></strong></td>
<td class="text-right"><%= @summary.fetch_quantity(product_drive.id) %></td>
<td class="text-right"><%= @summary.fetch_unique_item_count(product_drive.id) %></td>
<td class="text-right"><strong><%= dollar_value(@summary.fetch_value(product_drive.id)) %></strong></td>
<td class="text-right"><%= view_button_to product_drive_path(product_drive.id) %></td>
</tr>
<% end %>
Expand Down

0 comments on commit 596f5a6

Please sign in to comment.