Skip to content

fix dashboard query by using .preload - #3066

Merged
mroderick merged 2 commits into
codebar:masterfrom
davidmillen50:2982-dashboard-query-eager-loads-workshop-host-with-sponsors-in-one-join
Nov 2, 2026
Merged

mroderick merged 2 commits into
codebar:masterfrom
davidmillen50:2982-dashboard-query-eager-loads-workshop-host-with-sponsors-in-one-join

Conversation

@davidmillen50

@davidmillen50 davidmillen50 commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

related to #2982

@mroderick

Copy link
Copy Markdown
Collaborator

What this changes

DashboardQuery.upcoming_events joined :sponsors and :workshop_host in a single eager_load. Both associations go through workshop_sponsors, so the scoped has_one (where(host: true)) shares the join alias with :sponsors — the alias trap from #2975. Depending on the plan and row order, workshop_host came back nil or bound to a non-host sponsor.

The dashboard card reads the venue through WorkshopPresenter#venue (app/presenters/workshop_presenter.rb:31 → model.host), so a lost host renders the homepage card with no venue, or with the wrong sponsor as the venue.

The fix keeps :sponsors in the join and loads the host on its own with preload(workshop_host: :sponsor): one query for the scoped WorkshopSponsor, one batched query for its sponsors. Fixed cost of two queries per dashboard render, independent of the number of cards. The extracted upcoming_workshops method is a plain refactor.

Review

Verified against the diff, the post-image files, Workshop associations, and the presenter/render path: the production change is correct and the query shape improves on the eager_load baseline. Ship it, with one non-blocking note.

The new spec would still pass if the preload were removed. spec/queries/dashboard_query_spec.rb:34 asserts values only:

expect(result.values.flatten.select { |event| event.is_a?(Workshop) }.map(&:host))
  .to all(eq(host))

Workshop#host lazy-loads through workshop_host&.sponsor, so deleting preload(workshop_host: :sponsor) from app/queries/dashboard_query.rb:60 leaves every dashboard spec green while restoring a per-card query on the homepage. The events path already guards this with a query-count spec at spec/requests/event_card_render_query_cost_spec.rb:38; the dashboard path has no equivalent. Suggested: a dashboard counterpart to that spec, asserting the query count stays flat as the card count grows.

Two follow-ups, both pre-existing and outside this diff:

  • DashboardQuery.upcoming_events_for_user (app/queries/dashboard_query.rb:27-40) still eager_loads :sponsors without :workshop_host, and the dashboard action renders through the same presenter, so hosts lazy-load per workshop there.
  • The spec covers the happy path only. Host nil for a workshop with only non-host sponsors (the other half of the Events listing can render the wrong sponsor as venue (eager_load host loss) #2975 failure mode) is not asserted.

@mroderick
mroderick merged commit 7df06c0 into codebar:master Nov 2, 2026
12 checks passed
mroderick added a commit that referenced this pull request Nov 2, 2026
The host assertions added in #3066 only checked the resolved sponsor, so
dropping the preload in DashboardQuery would restore a per-card query and
leave the suite green.

Count SQL statements while reading the attributes a dashboard card
renders for one and four cards, require a non-zero baseline, and pin the
two host-less cases: only non-host sponsors resolves to nil, and no
sponsor rows renders without breakage.

Closes #3071
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.

3 participants