mirror of
https://github.com/we-promise/sure.git
synced 2026-04-09 15:24:48 +00:00
fix: Preserve tags on bulk edits (take 3) (#889)
* fix: handle tags separately from entryable_attributes in bulk updates Tags use a join table (taggings) rather than a direct column, which means empty tag_ids clears all tags rather than meaning "no change". This caused bulk category-only edits to accidentally clear existing tags. This fix: - Removes tag_ids from entryable_attributes in Entry.bulk_update! - Adds update_tags parameter to explicitly control tag updates - Uses params.key?(:tag_ids) in controller to detect explicit tag changes - Preserves existing tags when tag_ids is not provided in the request This is a cleaner architectural solution compared to tracking "touched" state in the frontend, as it properly acknowledges the semantic difference between column attributes and join table associations. https://claude.ai/code/session_014CsmTwjteP4qJs6YZqCKnY * fix: handle tags separately in API transaction updates Apply the same pattern to the API endpoint: tags are now handled separately from entryable_attributes to distinguish between "not provided" (preserve existing tags) and "explicitly set to empty" (clear all tags). This allows API consumers to: - Update other fields without affecting tags (omit tag_ids) - Clear all tags (send tag_ids: []) - Set specific tags (send tag_ids: [id1, id2]) https://claude.ai/code/session_014CsmTwjteP4qJs6YZqCKnY * Proposed fix * fix: improve tag handling in bulk updates for transactions * fix: allow bulk edit to clear/preserve tags by omitting hidden multi-select field * PR comments * Dumb copy/paste error * Linter --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com>
This commit is contained in:
committed by
GitHub
parent
8b89d24314
commit
c77971ea0d
@@ -257,6 +257,75 @@ class Api::V1::TransactionsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
test "should preserve tags when tag_ids not provided in update" do
|
||||
# Set up transaction with existing tags
|
||||
original_tags = [ Tag.first, Tag.second ]
|
||||
@transaction.tags = original_tags
|
||||
@transaction.save!
|
||||
|
||||
# Update only the name, without providing tag_ids
|
||||
update_params = {
|
||||
transaction: {
|
||||
name: "Updated Name Only"
|
||||
}
|
||||
}
|
||||
|
||||
put api_v1_transaction_url(@transaction),
|
||||
params: update_params,
|
||||
headers: api_headers(@api_key)
|
||||
assert_response :success
|
||||
|
||||
@transaction.reload
|
||||
assert_equal "Updated Name Only", @transaction.entry.name
|
||||
# Tags should be preserved since tag_ids was not in the request
|
||||
assert_equal original_tags.map(&:id).sort, @transaction.tag_ids.sort
|
||||
end
|
||||
|
||||
test "should clear tags when empty tag_ids explicitly provided in update" do
|
||||
# Set up transaction with existing tags
|
||||
@transaction.tags = [ Tag.first, Tag.second ]
|
||||
@transaction.save!
|
||||
|
||||
# Explicitly provide empty tag_ids to clear tags
|
||||
update_params = {
|
||||
transaction: {
|
||||
name: "Updated Name",
|
||||
tag_ids: []
|
||||
}
|
||||
}
|
||||
|
||||
put api_v1_transaction_url(@transaction),
|
||||
params: update_params,
|
||||
headers: api_headers(@api_key)
|
||||
assert_response :success
|
||||
|
||||
@transaction.reload
|
||||
# Tags should be cleared since tag_ids was explicitly provided as empty
|
||||
assert_empty @transaction.tags
|
||||
end
|
||||
|
||||
test "should update tags when tag_ids explicitly provided in update" do
|
||||
# Set up transaction with one tag
|
||||
@transaction.tags = [ Tag.first ]
|
||||
@transaction.save!
|
||||
|
||||
new_tags = [ Tag.second ]
|
||||
|
||||
update_params = {
|
||||
transaction: {
|
||||
tag_ids: new_tags.map(&:id)
|
||||
}
|
||||
}
|
||||
|
||||
put api_v1_transaction_url(@transaction),
|
||||
params: update_params,
|
||||
headers: api_headers(@api_key)
|
||||
assert_response :success
|
||||
|
||||
@transaction.reload
|
||||
assert_equal new_tags.map(&:id), @transaction.tag_ids
|
||||
end
|
||||
|
||||
# DESTROY action tests
|
||||
test "should destroy transaction" do
|
||||
entry_to_delete = @account.entries.create!(
|
||||
|
||||
Reference in New Issue
Block a user