Previously a user who linked the wrong account at creation had to
delete + recreate the goal. Now the edit modal carries the same
funding-accounts checkbox group as Step 1 of the stepper, pre-checked
with the goal's current links.
- GoalsController#edit loads @linkable_accounts + @currently_linked_account_ids.
- #update accepts account_ids; when supplied, runs the create / update
inside a Goal.transaction and syncs linked accounts via
sync_linked_accounts! (set-diff: destroy_all unselected goal_accounts,
create the new ones). Validates at least one account before touching
goal_accounts so the user gets a clean re-render.
- Removing an account preserves the goal's existing contributions —
GoalContribution#account_must_be_linked_to_goal only fires on save,
so historical rows stay valid.
- _form_edit partial accepts new locals; edit.html.erb threads them
through.
- 3 new controller tests: identity-only patch leaves links intact;
account_ids patch replaces the link set; empty account_ids
re-renders with error.
- index: STATE_FILTERS count loop replaced with single Current.family.goals.group(:state).count + per-state lookup. 5 SQL queries -> 1.
- GoalsController + GoalContributionsController: rescue_from ActiveRecord::RecordNotFound -> redirect_to goals_path with a flash. Affects stale deep links AND cross-family access (previously bare 404 -> Chrome error page). Test for cross-family access updated to assert the redirect + flash key.
- New locale key goals.errors.not_found.