mirror of
https://github.com/we-promise/sure.git
synced 2026-05-29 23:39:03 +00:00
feat(goals/edit): funding-accounts editor in the edit modal
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.
This commit is contained in:
@@ -71,20 +71,39 @@ class GoalsController < ApplicationController
|
||||
end
|
||||
|
||||
def edit
|
||||
@linkable_accounts = linkable_accounts_for_new
|
||||
@currently_linked_account_ids = @goal.goal_accounts.pluck(:account_id).map(&:to_s)
|
||||
end
|
||||
|
||||
def update
|
||||
if @goal.update(goal_update_params)
|
||||
flash[:notice] = t(".success")
|
||||
respond_to do |format|
|
||||
format.html { redirect_to goal_path(@goal) }
|
||||
format.turbo_stream do
|
||||
render turbo_stream: turbo_stream.action(:redirect, goal_path(@goal))
|
||||
end
|
||||
end
|
||||
else
|
||||
account_ids = params.dig(:goal, :account_ids)
|
||||
accounts_supplied = !account_ids.nil?
|
||||
accounts = accounts_supplied ? lookup_accounts(account_ids) : []
|
||||
|
||||
if accounts_supplied && accounts.empty?
|
||||
@goal.errors.add(:base, :at_least_one_linked_account_required)
|
||||
@linkable_accounts = linkable_accounts_for_new
|
||||
@currently_linked_account_ids = @goal.goal_accounts.pluck(:account_id).map(&:to_s)
|
||||
render :edit, status: :unprocessable_entity
|
||||
return
|
||||
end
|
||||
|
||||
Goal.transaction do
|
||||
@goal.update!(goal_update_params)
|
||||
sync_linked_accounts!(@goal, accounts) if accounts_supplied
|
||||
end
|
||||
|
||||
flash[:notice] = t(".success")
|
||||
respond_to do |format|
|
||||
format.html { redirect_to goal_path(@goal) }
|
||||
format.turbo_stream do
|
||||
render turbo_stream: turbo_stream.action(:redirect, goal_path(@goal))
|
||||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
@linkable_accounts = linkable_accounts_for_new
|
||||
@currently_linked_account_ids = @goal.goal_accounts.pluck(:account_id).map(&:to_s)
|
||||
render :edit, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def destroy
|
||||
@@ -148,6 +167,18 @@ class GoalsController < ApplicationController
|
||||
Current.family.accounts.where(accountable_type: "Depository").visible.alphabetically.to_a
|
||||
end
|
||||
|
||||
def sync_linked_accounts!(goal, accounts)
|
||||
desired = accounts.map(&:id).to_set
|
||||
current = goal.goal_accounts.pluck(:account_id).to_set
|
||||
|
||||
(current - desired).each do |id|
|
||||
goal.goal_accounts.where(account_id: id).destroy_all
|
||||
end
|
||||
(desired - current).each do |id|
|
||||
goal.goal_accounts.create!(account_id: id)
|
||||
end
|
||||
end
|
||||
|
||||
def create_initial_contribution_if_provided!(goal, accounts)
|
||||
amount = params.dig(:goal, :initial_contribution_amount)
|
||||
account_id = params.dig(:goal, :initial_contribution_account_id)
|
||||
|
||||
Reference in New Issue
Block a user