Skip to content

fix: on_match :destroy for many_to_many now destroys both join and destination#2638

Open
nallwhy wants to merge 2 commits intoash-project:mainfrom
nallwhy:fix/many-to-many-on-match-destroy
Open

fix: on_match :destroy for many_to_many now destroys both join and destination#2638
nallwhy wants to merge 2 commits intoash-project:mainfrom
nallwhy:fix/many-to-many-on-match-destroy

Conversation

@nallwhy
Copy link
Copy Markdown
Contributor

@nallwhy nallwhy commented Mar 18, 2026

Contributor checklist

Leave anything that you believe does not apply unchecked.

  • I accept the AI Policy, or AI was not used in the creation of this PR.
  • Bug fixes include regression tests
  • Chores
  • Documentation changes
  • Features include unit/acceptance tests
  • Refactoring
  • Update dependencies

Summary

  • Fixes on_match: :destroy for many_to_many relationships to destroy both the join record and the destination record, consistent with how on_missing: :destroy already works
  • Adds a new 3-tuple form {:destroy, :dest_action, :join_action} for explicit control over both actions
  • Adds many_to_many_destroy_destination_on_match? backward compatibility config:
    • false (default): {:destroy, action} 2-tuple only destroys the join record (old behavior)
    • true (set by installer for new projects): 2-tuple also destroys both join and destination
    • Will be removed in 4.0

Closes #859

Copilot AI review requested due to automatic review settings March 18, 2026 04:20
@nallwhy nallwhy marked this pull request as draft March 18, 2026 04:20
Copy link
Copy Markdown

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

Fixes manage_relationship behavior for many_to_many relationships so on_match: :destroy removes both the join row and the destination record (aligning with existing on_missing: :destroy semantics), while adding an explicit 3-tuple form for controlling destination vs join destroy actions.

Changes:

  • Update managed relationship option sanitization so on_match: :destroy (many-to-many) expands to a { :destroy, dest_action, join_action } form.
  • Add many-to-many-specific destroy handling for on_match in Ash.Actions.ManagedRelationships.
  • Add regression tests and update docs to describe the new behavior and new 3-tuple option.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/manage_relationship_test.exs Adds regression tests covering shorthand :destroy, 2-tuple backward compatibility, and new 3-tuple behavior for many-to-many on_match.
lib/ash/changeset/managed_relationship_helpers.ex Changes option sanitization + destination action introspection so many-to-many on_match: :destroy targets both destination and join.
lib/ash/changeset/changeset.ex Updates manage_relationship docs for on_match destroy semantics and documents the new 3-tuple.
lib/ash/actions/read/calculations.ex Formatting-only change to parent_stack: option layout.
lib/ash/actions/managed_relationships.ex Implements new many-to-many destroy path for on_match using separate destination + join destroy actions.

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

Comment thread lib/ash/actions/managed_relationships.ex
Comment thread lib/ash/actions/managed_relationships.ex Outdated
Comment thread lib/ash/changeset/changeset.ex Outdated
@nallwhy nallwhy force-pushed the fix/many-to-many-on-match-destroy branch from 4a3d674 to 4beb8f3 Compare March 18, 2026 04:48
@nallwhy nallwhy force-pushed the fix/many-to-many-on-match-destroy branch from 4beb8f3 to afbcb0e Compare March 18, 2026 04:53
@nallwhy nallwhy marked this pull request as ready for review March 18, 2026 04:53
@zachdaniel
Copy link
Copy Markdown
Contributor

@nallwhy I don't believe that we should retain backwards compatibility on the {:delete, :action} format necessarily. If we want to keep it backwards compatible we can add a backwards compatibility configuration for this?

@nallwhy
Copy link
Copy Markdown
Contributor Author

nallwhy commented Mar 19, 2026

Since we don't need to maintain backward compatibility for the {:destroy, action} format, I went ahead and simplified the implementation — the code is much cleaner this way.

@zachdaniel
Copy link
Copy Markdown
Contributor

Well, I think we may need to maintain backwards compatibility via a config of some kind, but I wouldn't want to have {:destroy, :action} destroy only the join, and {:destroy, :action, :action} destroy both for users moving forward. We can use a backwards compatibility configuration for this (documented in hex and you can also add it to the installer so it automatically uses the new nice behavior for new users). We'll strip that out in 4.0

@nallwhy nallwhy force-pushed the fix/many-to-many-on-match-destroy branch from 307efd5 to 4877171 Compare March 19, 2026 03:31
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.

Many to many and on match destroy in manage_relationship

3 participants