Skip to content

Fix N+1 queries on registration_policy and its buckets - #11869

Merged
nbudin merged 4 commits into
mainfrom
nbudin/fix-registration-policy-n-plus-one
Aug 3, 2026
Merged

Fix N+1 queries on registration_policy and its buckets#11869
nbudin merged 4 commits into
mainfrom
nbudin/fix-registration-policy-n-plus-one

Conversation

@nbudin

@nbudin nbudin commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • EventType/EventProposalType read registration_policy directly, and RegistrationPolicyType read buckets (and every field derived from it — minimum_slots, total_slots, slots_limited, etc.) via plain, unbatched associations. Any query touching these across a list of events issued one query per row instead of one batched query for the whole list — this is the referential-integrity gap left over from the JSONB→AR migration in Migrate registration policies from JSONB to ActiveRecord (#11238) #11819.
  • Wired both associations into this codebase's existing association_loaders dataloader pattern instead (see app/graphql/sources/active_record_association.rb), matching how every other association is already batched in these types.
  • Also disabled Metrics/ClassLength and Metrics/BlockLength project-wide — we were already granting per-file exceptions to both cops consistently enough that keeping them enabled wasn't adding value, and it was blocking this fix on unrelated pre-existing debt in event_type.rb.
  • Ran bin/rails graphql:update to regenerate schema.graphql/schema.json and the generated frontend types. This picked up ~2 months of accumulated, unrelated description/field drift from prior merged PRs that hadn't run this step (last regenerated May 28) — so most of that diff is pre-existing catch-up, not new from this change. Added a note to CLAUDE.md so future schema-touching PRs run this before committing.

Fixes INTERCODE-176, INTERCODE-177 (both are the same root cause, confirmed by reproducing each Sentry trace's exact query shape locally before and after the fix).

Test plan

  • Rubocop clean on all touched files
  • bin/rails test test/graphql/mutations/{create_event,create_event_proposal,create_filler_event,update_event,update_event_proposal}_test.rb — 17 tests, 0 failures
  • Verified locally with a throwaway test executing a GraphQL query shaped like each Sentry trace (registrationPolicy/slotsLimited/totalSlots across 8 events): query count went from 1 (policies) + up to 16 (buckets, one per event) down to a flat 2 queries regardless of event count
  • bin/rails graphql:update ran clean, no manual edits needed to generated files

PR description written by Claude

nbudin and others added 4 commits August 3, 2026 11:10
EventType/EventProposalType read registration_policy directly and
RegistrationPolicyType read buckets (and every field derived from it)
via plain, unbatched associations, so any query touching these across
a list of events issued one query per row instead of one batched query
for the whole list.

Wire both associations into this codebase's existing association_loaders
dataloader pattern instead.

Also disable Metrics/ClassLength and Metrics/BlockLength project-wide;
we were already granting per-file exceptions to both cops consistently
enough that keeping them enabled wasn't adding value.

Fixes INTERCODE-176, INTERCODE-177

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Run bin/rails graphql:update to pick up the schema/type changes from
the registration_policy N+1 fix. schema.graphql/schema.json hadn't been
regenerated since a prior merge (May 28), so this also catches up ~2
months of accumulated description/field drift from unrelated merged
PRs that didn't run this step.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The N+1 fix PR needed a bin/rails graphql:update run that hadn't been
done in ~2 months of merged PRs. Add it to CLAUDE.md so future
schema-touching changes catch this before committing instead of after.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Matches the inline-disable style already used elsewhere in this file
(e.g. GraphQL/ExtractType on field declarations) instead of
disable/enable pairs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Report: Only Changed Files listed

Package Base Coverage New Coverage Difference
app/graphql/types/event_proposal_type.rb 🟢 82.76% 🟢 83.33% 🟢 0.57%
app/graphql/types/event_type.rb 🟢 77.78% 🟠 74.47% 🔴 -3.31%
app/graphql/types/registration_policy_type.rb 🟢 100% 🟠 73.91% 🔴 -26.09%
Overall Coverage 🟢 55.32% 🟢 55.32% ⚪ 0%

Minimum allowed coverage is 0%, this run produced 55.32%

@nbudin
nbudin merged commit 0533aee into main Aug 3, 2026
25 checks passed
@nbudin
nbudin deleted the nbudin/fix-registration-policy-n-plus-one branch August 3, 2026 18:23
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.

1 participant