Problem/Motivation
The core entity reference field does not document any requirement that the main property name on the field is the same as the value of the entity ID.
However, the code in jsonapi module assumes this is true in at least a couple places. This breaks subclasses of EntityReferenceItem that use the UUID (e.g. entity_reference_uuid module) or some other unique identifier (e.g. the revision ID) as the main property.
related:
#3050845: Includes using the `entity_reference_uuid` contrib module not working
#3310170: Use UUID as entity ID
Steps to reproduce
Using the entity_reference_uuid module, try to include related data for the reference field, or try to send a PATCH request to the relationship URL
Proposed resolution
Since we are already loading the entity, we can simply use/assign the "entity" property on the reference field instead of trying to guess the mapping of entity ID to property name.
Remaining tasks
port contrib patch, update core patch
User interface changes
n/a
API changes
n/a
Data model changes
n/a
Release notes snippet
todo
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | 3476224-PATCH-use-entity-for-reference.patch | 2.31 KB | pwolanin |
Issue fork drupal-3476224
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
pwolanin commentedComment #5
bbralaOk, moved it to an issuefork so we can get tests.
Although this seems fine, we do need some testing around this. I guess testing the 2 changed methods might be good enough, but not entirely sure yet how to do that.
Comment #6
bbralaComment #7
bbralaComment #10
heddnThis has a failing test now on MR 11771
Comment #11
smustgrave commentedSeems there has already been a review.
Can the branches/MRs be cleaned up some for easier reviews
Thanks!
Comment #12
pwolanin commentedDiscussed with @tstoeckler in person who has run into similar issues using jsonapi. His feeling was the the branch where we've started adding the test is the best way to move forward - basically assuming that all entity reference fields have an "entity" computed field that we can use to associate the loaded entity
Comment #15
heddnWorking on some more test coverage and path to patch the addition of a relationship.
Comment #16
heddnThis adds more test coverage for adding relationships when target_id is not the main property. Interestingly, I stumbled upon the fact that JsonApiFunctionalTest does some very similar tests, but with more traditional entity reference fields. Of the 2 scenarios I've added, the first was the only one that actually didn't presently work. The second already worked but I added it so we don't have a regression in that scenario.
Comment #17
tstoecklerYes, thanks for managing the MRs @pwolanin that makes it more manageable. Yes, I agree with the proposed resolution. The only way this would be a breaking change would be if a custom entity reference implementation either did not provide a computed entity property at all - which would (among lots of other things!) break the entity query joining across the entity reference while having absolutely no benefit - or did provide one but did not manage the sync from the entity property to its target ID property - which just seems like a straight up bug. So I don't think this should be a reason to hold this up, in particular since this is an actual contrib blocker. I can't really imagine that there are actually people impacted by this, but will write a change notice for this just in case anyway.
And will do a proper code review afterwards.
Comment #18
tstoecklerDid not intend to unassign, apologies.
Comment #19
tstoecklerIn starting to write the change notice and looking at some of the code I found that - in addition to the current assumption of the main property that is discussed here - JSON:API currently also already assumes a computed entity property that is specifically called
'entity'. See\Drupal\jsonapi\IncludeResolver::resolveIncludeTree(). So what I said above is not true, there is no change that this property is required - because it already is. I think that is further evidence that the proposed approach is the correct and this is just consolidating different assumptions in different places to one assumption.Comment #20
bbralaFor reference. This was the commit:
#3057545: ResourceTypeRepository wrongly assumes that all entity reference fields have the setting "target_type": Issue #3057545 by acbramley, hchonov, bbrala, bradjones1, larowlan, yogeshmpawar, Leon Kessler, gease, joachim, gabesullice, kfritsche, jibran, Wim Leers, Berdir, smustgrave, alexpott, catch: ResourceTypeRepository wrongly assumes that all entity reference fields have the setting "target_type"
Comment #21
gábor hojtsyComment #22
heddnThanks to the helpful input. I've addressed all feedback on the MR. I re-tested if scenario #2 still works before/after this change and that is still the case. All that wasn't working is scenario #1.
Comment #23
tstoecklerWow, what awesome turnaround, thanks a lot. Looked through the changes and it looks great to me. I did spend some more time looking at the other usages of
getMainPropertyName(), but I'm not yet convinced there's actually anything actionable there, so not opening a follow-up issue for that. So there's really nothing left to do here from my point of view.Comment #24
tstoecklerHmm... strange, don't really understand why the Nightwatch tests would fail, but I guess would be good to get a green pipeline before this goes in.
Comment #25
bbralaNightwatch tests fail sometimes ramdomly, at that point, just hit retry and they will succeed most of the time.
Comment #26
alexpottCommitted 71cc5fd and pushed to 11.x. Thanks!
As we're in the RC phase going to backport this to 11.2.x once 11.2.0 is out.
Comment #28
xjmThanks everyone!
Contributed project blockers are generally major by default. Also, even if it weren't a contrib blocker, the bug sounds major to me on its own.
I think this is safe to backport during RC (and I would actually prefer it before 11.2.0 rather than in a patch release given the small internal change to behavior and assumptions as per the CR).
Crediting @alexpott for the previous commit; he was uncredited somehow.
Comment #30
xjm@catch also said in Slack that he thought it was RC-safe FWIW; crediting RM reviews.
Comment #32
alexpottThanks @xjm and @catch for considering this for backport. Committed 8d70081 and pushed to 11.2.x.
Comment #33
pwolanin commentedThanks!
We have been using a variant on this patch for a long time in production, would love to see it bakcport to 10.x so we don't have to keep applying a core patch.
Comment #35
xjmIt's not patch-eligible, but @catch and I did agree on backporting it to 10.6 since it's a major bug and a contributed project blocker, so it will at least be addressed with the December release. (Of course the bug will also go away when the site is upgraded to Drupal 11.) 😉
Comment #37
xjmLooks like it's not a clean backport, unfortunately:
So we would need a separate MR for backport.
Comment #39
xjmThe merge request might need another attempt. :)
Comment #40
pwolanin commentedIt looks like that static method
EntityTestHelper::createBundle()replaced a module functionentity_test_create_bundle()in #3495966: Deprecate and replace entity_test_create_bundle(), entity_test_delete_bundle() in 11.x, so for the backport we can switch it back.Comment #41
pwolanin commentedFixing the backport was just that 1-line fix to use the prior version of that test code helper function
Comment #45
xjmCommitted the backport to 10.6.x. Thanks!