-
Notifications
You must be signed in to change notification settings - Fork 823
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 Correctly remove relations with ManyManyThroughList::removeall #10295
FIX Correctly remove relations with ManyManyThroughList::removeall #10295
Conversation
Given that the join records are DataObjects in their own right, do you think we’d be better approaching this in a similar way to |
Hmm I'm conflicted between wanting to keep it performant and wanting to let people use those extension points... Would it be reasonable to make it configurable? We could add a new configuration boolean on the join record class (something like Then in removeall if that config is falsey we use this or a similar approach, and if it's true we use the ORM so that any project that explicitly needs those hooks called on a join record can have that functionality available. Keeps it snappy for the majority but gives flexibility to the minority that need it. |
Maintaining two codepaths based on a config flag isn’t ideal 😕 I think we should be consistent with how we handle the “through” records too. When Performance-wise there shouldn’t really be any noticeable difference until you reach hundreds/thousands of join records. That sort of thing tends to be handled by scheduled tasks rather than synchronous user actions. |
Just rethinking this, we’re changing behaviour from un-assigning a join record to deleting a join record. For old Would we be safer to change this PR to just fix the filter issue and leave the “unassign” behaviour in place? |
I think the "unassign" behaviour is categorically a bug. If I call I think I'll wait a bit and see if anyone else opines before I make any changes. |
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.
It looks good, though could you bump up the number of fixtures used here from 2 to 3. Reason being is so that we can filter out 2 and assert there is 1 remaining, this is just to ensure it's removing 'all' rather than 'first'
Also, if there's not a test already, could you also add a test for ->removeAll() on an unfiltered list just to ensure that it removes everything
@emteknetnz do you have any opinions on using |
Discussed with @emteknetnz offline - he says it makes sense to use the ORM for this situation, so that's two in favour of the ORM. I'll take that approach. |
That's part of this same |
Instead of just setting one side of the relation to null in the through list, remove the rows entirely. Remove only the relations which match the filters that have already been set on the list. This is consistent with the way ManyManyList works. Also some small tidy-up (removing an unnecessary line break and an unused "use" statement)
aa3ea28
to
19bb72e
Compare
NOTE I have also changed the IDs passed into the remove callbacks - the
|
I have approved, but there is some Travis test failed. Could you check it please.
@emteknetnz, could you have a look, please |
FYI the failure is on the |
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 at first glance.
Can you just confirm what happens in the following scenarios:
- the same relations is defined multiple times. e.g.: Example Class A has a many-many relation to Class B. One object A is related multiple times to the same Object B.
- What happens if the ManyManyThrouh object is versioned? Do we want to add a unit test specifically for that?
Just want to make sure we've covered all our basis.
As mentioned in another comment this isn't really supported - but if you do manage to get a duplicate relation, it is appropriately cleared out with the call to
I don't know what if any thought was put into this scenario when
Given the above, I think versioning is out of scope for this PR. At most, I could add a note in the docs that versioning the join objects isn't currently supported. |
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.
My pesky question have been addressed.
Instead of just setting one side of the relation to null in the through table, remove the rows entirely.
Remove only the relations which match the filters that have already been set on the list.
This is consistent with the way
ManyManyList
works - in fact much of the code for the tests are taken straight from that class.The issue was ultimately caused by the
HasManyList
which is being used as an intermediary not having and of the 'where' clause (i.e. filter/exclude) of the underlying dataquery of theManyManyThroughList
. Changing that without causing regressions seemed like a bit of a tricky way to handle this - and even then if we still relied on usingremoveAll()
from thatHasManyList
we would have still seen the rows in the through table being updated with null IDs on one side of the relationship instead of those rows being deleted outright.Also some small tidy-up (removing an unnecessary line break and an unused "use" statement)
Parent Issue