Skip to content

Change order of operations in persist_changes#781

Open
jamiebenstead wants to merge 1 commit intomainfrom
1268-fix-components-extension-cant-be-blank-error
Open

Change order of operations in persist_changes#781
jamiebenstead wants to merge 1 commit intomainfrom
1268-fix-components-extension-cant-be-blank-error

Conversation

@jamiebenstead
Copy link
Copy Markdown
Contributor

Description

Attempted fix for Sentry errors saying Validation failed: Components extension can't be blank (ActiveRecord::RecordInvalid)
Example here

Status

What's changed?

Update the order of operations in persist_changes. Currently we validate and save before deleting components marked for deletion. If one of the components is invalid and going to be deleted this will cause save to fail.

…o save the project before components are removed
Copilot AI review requested due to automatic review settings April 10, 2026 09:59
@cla-bot cla-bot bot added the cla-signed label Apr 10, 2026
@github-actions
Copy link
Copy Markdown

Test coverage

89.61% line coverage reported by SimpleCov.
Run: https://github.com/RaspberryPiFoundation/editor-api/actions/runs/24237484698

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reorders persistence steps in Project::Update.persist_changes to delete components marked for removal before saving the project, aiming to prevent ActiveRecord::RecordInvalid when soon-to-be-deleted components fail validation.

Changes:

  • Move component deletions (destroy_all) ahead of project.save! inside the transaction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


ActiveRecord::Base.transaction do
response[:project].save!
response[:project].components.where(id: response[:component_ids_to_delete]).destroy_all
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because update_component_attributes enumerates response[:project].components, the association is loaded before persist_changes. Calling components.where(...).destroy_all may not reliably remove those destroyed records from the already-loaded association cache, so project.save! can still validate the destroyed components and fail (potentially keeping the Sentry error). Prefer deleting via the association proxy (e.g., response[:project].components.destroy(response[:component_ids_to_delete])) or otherwise ensuring the in-memory collection no longer contains the records being deleted before save! runs validations.

Suggested change
response[:project].components.where(id: response[:component_ids_to_delete]).destroy_all
response[:project].components.destroy(response[:component_ids_to_delete])

Copilot uses AI. Check for mistakes.
Comment on lines 82 to 88
def persist_changes(response)
return if response.failure?

ActiveRecord::Base.transaction do
response[:project].save!
response[:project].components.where(id: response[:component_ids_to_delete]).destroy_all
response[:project].save!
end
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is intended to fix a validation failure when an invalid component is being deleted. There are existing unit specs for Project::Update under spec/concepts/project/; please add a regression test that reproduces the failure (invalid component present but omitted from update_hash[:components]) and asserts the update succeeds and the invalid component is removed.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants