Recalculate stats when an import is deleted.

This commit is contained in:
Eugene Burmakin 2025-09-22 20:30:10 +02:00
parent f8a05e68e3
commit 6e44425e4e
3 changed files with 35 additions and 3 deletions

View file

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Prometheus exporter is now not being started when console is being run. - Prometheus exporter is now not being started when console is being run.
- Stats will now properly reflect countries and cities visited after importing new points. - Stats will now properly reflect countries and cities visited after importing new points.
- `GET /api/v1/points will now return correct latitude and longitude values. #1502 - `GET /api/v1/points will now return correct latitude and longitude values. #1502
- Deleting an import will now trigger stats recalculation for affected months. #1789
## Changed ## Changed

View file

@ -11,6 +11,7 @@ class Import < ApplicationRecord
after_commit -> { Import::ProcessJob.perform_later(id) unless skip_background_processing }, on: :create after_commit -> { Import::ProcessJob.perform_later(id) unless skip_background_processing }, on: :create
after_commit :remove_attached_file, on: :destroy after_commit :remove_attached_file, on: :destroy
before_commit :recalculate_stats, on: :destroy, if: -> { points.exists? }
validates :name, presence: true, uniqueness: { scope: :user_id } validates :name, presence: true, uniqueness: { scope: :user_id }
validate :file_size_within_limit, if: -> { user.trial? } validate :file_size_within_limit, if: -> { user.trial? }
@ -63,8 +64,14 @@ class Import < ApplicationRecord
def file_size_within_limit def file_size_within_limit
return unless file.attached? return unless file.attached?
if file.blob.byte_size > 11.megabytes return unless file.blob.byte_size > 11.megabytes
errors.add(:file, 'is too large. Trial users can only upload files up to 10MB.')
errors.add(:file, 'is too large. Trial users can only upload files up to 10MB.')
end
def recalculate_stats
years_and_months_tracked.each do |year, month|
Stats::CalculatingJob.perform_later(user.id, year, month)
end end
end end
end end

View file

@ -31,7 +31,7 @@ RSpec.describe Import, type: :model do
describe 'file size validation' do describe 'file size validation' do
context 'when user is a trial user' do context 'when user is a trial user' do
let(:user) do let(:user) do
user = create(:user) user = create(:user)
user.update!(status: :trial) user.update!(status: :trial)
user user
@ -116,4 +116,28 @@ RSpec.describe Import, type: :model do
end end
end end
end end
describe '#recalculate_stats' do
let(:import) { create(:import, user:) }
let!(:point1) { create(:point, import:, user:, timestamp: Time.zone.local(2024, 11, 15).to_i) }
let!(:point2) { create(:point, import:, user:, timestamp: Time.zone.local(2024, 12, 5).to_i) }
it 'enqueues stats calculation jobs for each tracked month' do
expect do
import.send(:recalculate_stats)
end.to have_enqueued_job(Stats::CalculatingJob)
.with(user.id, 2024, 11)
.and have_enqueued_job(Stats::CalculatingJob).with(user.id, 2024, 12)
end
context 'when import has no points' do
let(:empty_import) { create(:import, user:) }
it 'does not enqueue any jobs' do
expect do
empty_import.send(:recalculate_stats)
end.not_to have_enqueued_job(Stats::CalculatingJob)
end
end
end
end end