Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/cascade destroy #1734

Merged
merged 8 commits into from
Jan 29, 2025
Merged

Fix/cascade destroy #1734

merged 8 commits into from
Jan 29, 2025

Conversation

barnabasJ
Copy link
Contributor

@barnabasJ barnabasJ commented Jan 27, 2025

fixes the test in ash-project/ash_postgres#466

@barnabasJ
Copy link
Contributor Author

I'm not to happy with having to have the before_batch there. But I didn't now how to do it without it.

@barnabasJ barnabasJ self-assigned this Jan 27, 2025
@barnabasJ barnabasJ added the bug Something isn't working label Jan 27, 2025
lib/ash/actions/destroy/bulk.ex Show resolved Hide resolved
lib/ash/resource/change/cascade_update.ex Outdated Show resolved Hide resolved
test/resource/changes/cascade_destroy_test.exs Outdated Show resolved Hide resolved
@barnabasJ barnabasJ requested a review from zachdaniel January 27, 2025 14:55
@zachdaniel
Copy link
Contributor

Alright, so, I think we need to have both the old behavior and the new behavior as options. There are two reasons:

  1. you can use cascade_destroy on an update action, which would be doable after the action
  2. you can defer the constraints that would cause a foreign key error, as a performance improvement.

@barnabasJ
Copy link
Contributor Author

barnabasJ commented Jan 27, 2025

Alright, so, I think we need to have both the old behavior and the new behavior as options. There are two reasons:

1. you can use `cascade_destroy` on an update action, which would be doable after the action

2. you can defer the constraints that would cause a foreign key error, as a performance improvement.

Sounds good, one more thing though. I stumbled upon this not because of a foreign key error but because it would hit this line

because it had a parent reference, but the load did not return any results anymore because the parent record was not in the db anymore. Should we return a different error here if the change is exectued as part of a destroy action and uses the old behaviour?

@zachdaniel
Copy link
Contributor

Ohhhhh right. So the right answer here is also a bit frustrating to implement probably.

If the action is a destroy action, we should try to do it without loading data actually.

What that looks like is:

  • If the relationship filter has no parent references and the relationship is not a many_to_many (I think this doesn't support many to many anyway)
    • then we extract the source_attribute, and construct a query against the destination for the specific id matches that exist plus the relationship.filter
    • unless no_attributes? true in which case we just use the query as is

Otherwise for destroy actions they must use the new before_batch behavior.

@barnabasJ
Copy link
Contributor Author

Ohhhhh right. So the right answer here is also a bit frustrating to implement probably.

If the action is a destroy action, we should try to do it without loading data actually.

What that looks like is:

* If the relationship filter has no parent references and the relationship is not a many_to_many (I think this doesn't support many to many anyway)
  
  * then we extract the source_attribute, and construct a query against the destination for the specific id matches that exist plus the relationship.filter
  * unless `no_attributes? true` in which case we just use the query as is

Otherwise for destroy actions they must use the new before_batch behavior.

I think that is pretty much what it is doing, isn't it? So in the error case we just need to check if we are in the after_action part of a a destroy action and if so return an error?

@zachdaniel
Copy link
Contributor

lol. Yep, sorry. Was early when I was first responding, hadn't had my coffee yet.

So I think the only thing needed here is to make this behavior opt-out, but opting out would raise an error if it gets to that error case and is an after action as you mentioned.

@barnabasJ barnabasJ requested review from zachdaniel and removed request for zachdaniel January 29, 2025 13:16
@zachdaniel
Copy link
Contributor

Ready to go?

@zachdaniel zachdaniel merged commit 962a472 into main Jan 29, 2025
36 checks passed
@zachdaniel
Copy link
Contributor

🚀 Thank you for your contribution! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants