-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Rework one-to-one relationships to remove existing instead of panicking #20232
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
Rework one-to-one relationships to remove existing instead of panicking #20232
Conversation
} | ||
|
||
if let Some(current_source) = current_source_to_remove { | ||
world.commands().entity(current_source).try_remove::<Self>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this have a race condition if we do a batch insert, similar to the one #19519 fixed? If we insert multiple one-to-one relationship sources without flushing, this will remove any previous source from the target, but I think later sources in the batch will overwrite earlier ones without removing.
This might be easier to fix if we merge #19932 first and do this whole check inside the command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
I'm still worried about reintroducing a race condition in batch inserts, especially since we just fixed one there, but we can probably fix that in a follow up after #19932.
Co-authored-by: Chris Russell <[email protected]>
Objective
Solution
on_insert
hook in theRelationship
trait to detect one-to-one relationships (where the target collection type isEntity
) and automatically remove any existing relationship before establishing the new one.TypeId
to identify one-to-one vs one-to-many relationships.try_remove()
to handle edge cases gracefully.Testing
Entity::add()
andEntity::extend_from_iter()
methods that would previously crash when attempting to establish overlapping one-to-one relationshipsone_to_one_relationship_shared_target
by removing#[should_panic]
and adding assertions to verify:- Original relationship is properly removed
- New relationship is correctly established
- Target entity points to the new source