Fix budget cache invalidation after transaction deletion#2808
Fix budget cache invalidation after transaction deletion#2808sure-admin wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthrough
ChangesFamily entry cache invalidation
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 392d264524
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| ts = entries.maximum(:updated_at) | ||
| ts.present? ? ts.to_i : 0 | ||
| end | ||
| "#{entries.count}-#{entries.maximum(:updated_at)&.to_f || 0}" |
There was a problem hiding this comment.
Avoid two full-ledger scans per cache lookup
When a report spans multiple periods, every distinct IncomeStatement#totals_query cache lookup invokes this method; removing memoization makes each invocation issue separate COUNT and MAX queries across all entries in the family. For example, the monthly loop in ReportsController#build_trends_data now adds two family-wide aggregate queries per month even when every report result is already cached, so long-range reports for large ledgers can become substantially slower or time out. Preserve deletion-aware invalidation without recomputing both aggregates for every cache fetch, such as by maintaining a mutation-driven version or safely reusing one aggregate snapshot.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/models/family.rb (1)
432-432: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winAvoid two aggregate queries per cache-version read.
This now issues separate
COUNTandMAX(updated_at)queries on every invocation, whileIncomeStatementreads the version for multiple cache keys. Combine the aggregates into one query or reuse a maintained invalidation token. As per coding guidelines, database access in models should be optimized.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/models/family.rb` at line 432, Optimize the cache-version calculation in the surrounding Family model method so each invocation does not issue separate COUNT and MAX(updated_at) aggregate queries. Fetch both aggregate values with one database query, or reuse an existing maintained invalidation token, while preserving the current version format and behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/models/family.rb`:
- Line 432: Replace the cache-key fragment using entries.count and maximum
updated_at with a family-level invalidation token that changes on every entry
create, update, and destroy. Update the relevant Family and entry lifecycle
logic so IncomeStatement cache keys always change after any material entry
mutation, including edits to non-latest entries.
---
Nitpick comments:
In `@app/models/family.rb`:
- Line 432: Optimize the cache-version calculation in the surrounding Family
model method so each invocation does not issue separate COUNT and
MAX(updated_at) aggregate queries. Fetch both aggregate values with one database
query, or reuse an existing maintained invalidation token, while preserving the
current version format and behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 973399fb-6e70-4807-bebe-e34796fd2816
📒 Files selected for processing (2)
app/models/family.rbtest/models/family_test.rb
| ts = entries.maximum(:updated_at) | ||
| ts.present? ? ts.to_i : 0 | ||
| end | ||
| "#{entries.count}-#{entries.maximum(:updated_at)&.to_f || 0}" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Invalidate on every material entry mutation.
entries.count plus the maximum updated_at is unchanged when a non-latest entry is edited, such as changing its amount, category, or date. Because IncomeStatement uses this value in cache keys, stale aggregation results can be served. Use a family-level invalidation token/timestamp updated on every entry create, update, and destroy, or another mechanism with that guarantee.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/models/family.rb` at line 432, Replace the cache-key fragment using
entries.count and maximum updated_at with a family-level invalidation token that
changes on every entry create, update, and destroy. Update the relevant Family
and entry lifecycle logic so IncomeStatement cache keys always change after any
material entry mutation, including edits to non-latest entries.
|
Reviewed the diff ( Correctness: This does fix a real gap. The old Test coverage: One concern worth addressing: dropping the Otherwise this looks correct, minimal, and in line with repo conventions (fat model, no new deps, no i18n surface). Generated by Claude Code |
Summary
Family#entries_cache_versionto include both entry count and latestupdated_atTests
bin/rails test test/models/family_test.rb test/controllers/transactions/bulk_deletions_controller_test.rb test/models/budget_test.rbSummary by CodeRabbit