Skip to content

Preload transfer counterparty associations on transactions index#2819

Open
bittensorrider wants to merge 25 commits into
we-promise:mainfrom
bittensorrider:perf/transactions-ctrl-index-html
Open

Preload transfer counterparty associations on transactions index#2819
bittensorrider wants to merge 25 commits into
we-promise:mainfrom
bittensorrider:perf/transactions-ctrl-index-html

Conversation

@bittensorrider

@bittensorrider bittensorrider commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes Skylight N+1 on TransactionsController#index where transfer rows repeatedly loaded transactionsentriesaccounts by id
  • Root cause: Transfer#categorizable? / #payment? walk inflow_transaction.entry.account during category menu render without nested includes
  • Adds a regression test that asserts those three by-id query patterns stay empty

Fix

Fixes #2818

Test plan

  • Open /transactions with several transfer rows; confirm list/category UI still renders
  • Confirm CI green for test/controllers/transactions_controller_test.rb
  • Optionally capture SQL: no repeated WHERE "transactions"."id" = ? / entryable_id / accounts.id during list render

Summary by CodeRabbit

  • Bug Fixes
    • Improved the Transactions index for transfer records by preloading the nested inflow/outflow entry and related account data, making transfer counterparty display more efficient.
  • Tests
    • Added an integration test that exercises the transfer index rendering path and confirms it avoids per-record database lookups when showing transfer outflow counterparties.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cd5c5dc8-9cfd-446c-8c97-38ad6fdb5165

📥 Commits

Reviewing files that changed from the base of the PR and between db72596 and 89df259.

📒 Files selected for processing (1)
  • test/controllers/transactions_controller_test.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/controllers/transactions_controller_test.rb

📝 Walkthrough

Walkthrough

The transactions index now eager-loads nested transfer counterparty transaction, entry, and account associations. An integration test verifies transfer rendering without repeated per-transfer queries.

Changes

Transfer eager loading

Layer / File(s) Summary
Preload transfer counterparties and validate queries
app/controllers/transactions_controller.rb, test/controllers/transactions_controller_test.rb
The index preloads transfer inflow/outflow paths through entries to accounts. Integration coverage verifies rendered transfer entries and detects repeated transaction, entry, and account lookups.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • we-promise/sure#2127: Adjusts transactions index loading for transfer-related transaction, entry, and account data.
  • we-promise/sure#2643: Adds nested transfer counterparty eager loading in TransactionsController#index.

Suggested labels: performance

Suggested reviewers: jjmata

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: preloading transfer counterparty associations on transactions index.
Linked Issues check ✅ Passed The controller preload change and regression test directly address the N+1 transfer counterparty lookups described in #2818.
Out of Scope Changes check ✅ Passed The diff stays focused on the transactions index preload fix and its test coverage, with no unrelated changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@test/controllers/transactions_controller_test.rb`:
- Around line 735-746: Update the transaction index test around the six
create_transfer calls to retain the created transfer records, then assert that
their DOM IDs or an equivalent transfer-row marker are present in the GET
transactions_url response before validating captured SQL queries. Keep the
existing query assertions unchanged.
- Around line 750-755: Broaden the SQL regression assertions in the transaction
list-render test so they detect any per-transfer lazy loads for transactions,
entries, and accounts, regardless of equality versus IN predicates, key
formatting, or adapter-generated whitespace. Prefer normalizing captured queries
before counting association loads, while preserving the expectation that each
association is eager-loaded without extra per-row queries.
🪄 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: 3cd94a79-e4ae-4c5c-97d7-9555e260aac4

📥 Commits

Reviewing files that changed from the base of the PR and between c9a28e1 and aa8f2bd.

📒 Files selected for processing (2)
  • app/controllers/transactions_controller.rb
  • test/controllers/transactions_controller_test.rb

Comment thread test/controllers/transactions_controller_test.rb Outdated
Comment thread test/controllers/transactions_controller_test.rb Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aa8f2bd728

ℹ️ 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".

Comment thread app/controllers/transactions_controller.rb Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/controllers/transactions_controller_test.rb (1)

781-792: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid classifying single-record IN (?) queries as lazy loads.

All six transfers use the same to_account, so the nested account preload can legitimately generate accounts.id IN (?). Since single_record_lookups currently matches a single-value IN (...), the test may fail even when eager loading is correct. Match only column = ? lookups, or use multiple counterparty accounts and assert the preload includes the expected IDs.

🤖 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 `@test/controllers/transactions_controller_test.rb` around lines 781 - 792, The
single_record_lookups matcher currently treats single-value IN queries as lazy
loads, causing valid nested preloads to be misclassified. Update
single_record_lookups to match only column = ? lookups, or adjust the test data
to use multiple counterparty accounts and assert the preload contains their
expected IDs; preserve batch preload detection.
🤖 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.

Outside diff comments:
In `@test/controllers/transactions_controller_test.rb`:
- Around line 781-792: The single_record_lookups matcher currently treats
single-value IN queries as lazy loads, causing valid nested preloads to be
misclassified. Update single_record_lookups to match only column = ? lookups, or
adjust the test data to use multiple counterparty accounts and assert the
preload contains their expected IDs; preserve batch preload detection.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d8dc74d4-f9d6-4393-be75-0dbab8336312

📥 Commits

Reviewing files that changed from the base of the PR and between 5be95ce and db72596.

📒 Files selected for processing (2)
  • app/controllers/transactions_controller.rb
  • test/controllers/transactions_controller_test.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/controllers/transactions_controller.rb

@jjmata jjmata left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested includes correctly targets what Transfer#categorizable?/#payment? actually walk (inflow_transaction.entry.account) for both the transfer_as_inflow and transfer_as_outflow sides, and skipping outflow_transaction per the inline comment looks right given the kind-check happens against the current Transaction, not the transfer object.

The regression test is a good addition — asserting on normalized SQL patterns for the three specific by-id lookups (transactions.id =, entries.entryable_id =, accounts.id =) rather than just a total query count makes it robust to unrelated query-count churn elsewhere on the page, and the comment distinguishing lazy = ? loads from legitimate nested-preload IN (...) is a nice touch to avoid false positives.

No concerns — this is exactly the class of "avoid N+1 in a global/high-traffic view" fix the project prioritizes.


Generated by Claude Code

@bittensorrider

Copy link
Copy Markdown
Contributor Author

@jjmata Thanks for the review. Glad this matches the intended preload path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: TransactionsController#index N+1 on transfer counterparty lookups

2 participants