Skip to content

[Views] Pass card, card grant and transfer ivars to partials as strict locals - #15205

Open
Luke-Oldenburg wants to merge 2 commits into
strict-locals-ivars-4-filtersfrom
strict-locals-ivars-5-cards
Open

Luke-Oldenburg wants to merge 2 commits into
strict-locals-ivars-4-filtersfrom
strict-locals-ivars-5-cards

Conversation

@Luke-Oldenburg

@Luke-Oldenburg Luke-Oldenburg commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Note

This is one PR in a stack split out of #15191. Review and merge them in order. Each PR's base branch is the PR before it, so its diff shows only its own change.

  1. [Views] Declare strict locals on the remaining partials that take locals #15191 Declare strict locals on the remaining partials that take locals
  2. [Views] Read strict locals instead of local_assigns #15200 Read strict locals instead of local_assigns
  3. [Views] Remove partial ivars that can't simply become locals #15201 Remove partial ivars that can't simply become locals
  4. [Views] Pass layout, login and mailer ivars to partials as strict locals #15202 Pass layout, login and mailer ivars to partials as strict locals
  5. [Views] Pass donation page and FullStory ivars to partials as strict locals #15203 Pass donation page and FullStory ivars to partials as strict locals
  6. [Views] Pass filter values to the filter partials as strict locals #15204 Pass filter values to the filter partials as strict locals
  7. [Views] Pass card, card grant and transfer ivars to partials as strict locals #15205 Pass card, card grant and transfer ivars to partials as strict locals ← this PR
  8. [Views] Pass event home, settings, invoice and G Suite ivars to partials as strict locals #15206 Pass event home, settings, invoice and G Suite ivars to partials as strict locals
  9. [Views] Pass comment, receipt form and HCB code history ivars to partials as strict locals #15207 Pass comment, receipt form and HCB code history ivars to partials as strict locals
  10. [Views] Pass @event and row options through navs and transaction rows as strict locals #15208 Pass @event and row options through navs and transaction rows as strict locals

Summary of the problem

Partials read instance variables that the controller, or the template rendering them, happened to set. Those inputs don't appear in the partial's strict locals declaration from #15191, nothing checks that a caller provides them, and a partial rendered from a page that didn't set the ivar silently gets nil.

This part of the stack turns each ivar a partial reads into a declared local that its callers pass. It was the fourth commit on #15191 (324 files), split by area so each part can be reviewed on its own. With every PR merged, the code is that commit's, except in three partials that got the same object under two names. Those now read the local they already had (in #15205, #15206 and #15208).

Describe your changes

  • Stripe cards: _stripe_card, _details, _form, _name_form, _shipping, _actions and actions/_rename.
  • Card grants: _actions, _buttons, _card_details, _create_form, _create_modal, _edit_nav and the actions/* partials, plus events/_card_grant_actions and events/_event_cards_table.
  • Transfers: events/transfers/_modal and _form, and events/_unauthorized_callout, which gets event from every transfer form that renders it (ACH, check, PayPal, wire, Wise, payments, contractors and grants).
  • card_grants/_create_form's defined?(@popover) && @popover is now a plain check on the popover local.
  • stripe_cards/_name_form reads card, which stripe_cards/edit passes from @card. stripe_cards/actions/_rename passes it card: stripe_card, so _actions and _rename still declare only stripe_card: (second commit).

How each conversion works

  • Templates, layouts, controllers and mailer templates pass x: @x. A partial in between passes its own local along. Where a partial already had a local holding the same object, it reads that local instead of getting a second copy.
  • A local is required when the body calls a method on it without a nil check. Otherwise it defaults to nil.
  • Every render call passes every new local, including the nil-default ones, so no partial falls back to a default the ivar didn't have.

Testing

  • The strict-locals checker reports no mismatches on this branch. A second check confirms that every statically resolved call to a partial this PR changes passes every local the PR adds. Every changed template compiles. The checker also reports no mismatches with this branch merged into current main.
  • I rendered 651 full pages through the full Rack stack as an admin, inside a rolled-back transaction on the dev DB, on [Views] Read strict locals instead of local_assigns #15200's head and on this branch as first opened, before the duplicate locals were folded together. They include filtered ledgers and transaction lists, card filters, popover and Turbo-Frame transaction pages, ledger items, settings pages and comment edit pages. The HTML is identical once CSRF tokens, nonces, record ids, timestamps, the invoice links Stripe signs per request, and the randomly picked greeting text are normalized.
  • I also rendered the payment and payroll forms with the payments flag on, and the Emburse overview with temporary Emburse transactions, as an admin and as a reader on four events. That covers both sides of the transfer layout's flag and the running sums. The HTML is identical.
  • For the second commit, the checker still reports no mismatches, on its own and merged into main, and erb_lint reports no offenses. I rendered every stripe card's show and edit page and the organizer removal form for 15 organizer positions before and after folding them, with the dev DB's cards temporarily set active so the rename modal and the active-card warning render. The HTML is identical.

🤖 Generated with Claude Code

…t locals

The stripe card and card grant partials, events/_card_grant_actions,
_event_cards_table and _unauthorized_callout, and events/transfers/_modal
and _form now take the ivars they read as declared locals.
_unauthorized_callout gets event from every transfer form that renders
it, including the payment and payroll forms. card_grants/_create_form's
defined?(@Popover) && @Popover becomes a check on the popover local.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ard local

stripe_cards/_actions and actions/_rename got stripe_card: @card and
card: @card, the same object under two names, only so _rename could
pass card on to _name_form. _rename now passes card: stripe_card, and
both partials go back to declaring just stripe_card:.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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