Skip to content

Commit a50d3a2

Browse files
committed
refactor rating calculations for performance
1 parent f5924f7 commit a50d3a2

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

app/models/service.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,14 @@ def sort_service_points(points)
6161
end
6262
end
6363

64+
# Avoid the .select {} Ruby loop.
65+
# Filter on status and case_id in SQL (far faster).
66+
# Preload associated cases to avoid N+1.
6467
def approved_points
65-
points.select { |p| p.status == 'approved' && !p.case.nil? }
68+
points
69+
.includes(:case)
70+
.where(status: 'approved')
71+
.where.not(case_id: nil)
6672
end
6773

6874
def perform_calculation

lib/tasks/service.rake

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
namespace :service do
2-
desc "Calculate the ratings for each service and store in db"
2+
desc "Recalculate ratings for all services (in batches)"
33
task perform_rating: :environment do
4-
services = Service.all
5-
services.each do |service|
6-
initial_rating = service.rating
7-
new_rating = service.calculate_service_rating
8-
if initial_rating != new_rating
9-
service.rating = new_rating
10-
service.save(validate: false)
11-
12-
version = Version.new
13-
version.item_type = "Service"
14-
version.item_id = service.id
15-
version.event = "update"
16-
version.whodunnit = "21311"
17-
version.object_changes = "This has been an automatic update by an official ToS;DR bot. The rating for this service changed from #{initial_rating} to #{new_rating}."
18-
version.save
4+
batch_size = 100
5+
Service.find_in_batches(batch_size: batch_size) do |services|
6+
services.each do |service|
7+
recalculate_service_rating(service)
198
end
209
end
2110
end
22-
11+
12+
def recalculate_service_rating(service)
13+
initial_rating = service.rating
14+
new_rating = service.calculate_service_rating
15+
16+
return if new_rating == initial_rating
17+
18+
service.update_columns(rating: new_rating, updated_at: Time.current)
19+
20+
Version.create!(
21+
item_type: "Service",
22+
item_id: service.id,
23+
event: "update",
24+
whodunnit: "21311",
25+
object_changes: "This has been an automatic update by an official ToS;DR bot. The rating for this service changed from #{initial_rating} to #{new_rating}."
26+
)
27+
end
2328

2429
desc "Mark as reviewed if approved points are over 20"
2530
task mark_as_reviewed: :environment do

0 commit comments

Comments
 (0)