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

When normalising relation field value, respect the empty array #16428

Conversation

i-just
Copy link
Contributor

@i-just i-just commented Jan 14, 2025

Description

Issue:

  • have entry type has two instances of the same relation field, and the second instance has a changed handle
  • create an entry of that type, leave the first instance of the field empty, and fill the second with at least one value (related element)
  • query the entry and use lazy eager loading (.eagerly()) to get content of both field instances
  • notice that the first instance is incorrectly populated with the content of the second instance

Solution:
When normalising the relation field value and the value passed to the method is an empty array, it means that the target IDs are already stored in the elements_sites.content column but as an empty array (the field is empty). Having a value there, even if it’s an empty array, means that the content was saved since v5.3.0, and the field is supposed to be empty.

Passing an empty array to the query means that the getEagerLoadingMap() method sees the value as an array, which means it then doesn’t attempt to check if the field is the first instance and incorrectly assign the content of the other instance of this field from the relations table.

Related issues

#16191


Detailed replication steps

  • create a blog channel with an entry type (it doesn’t have to have any fields; just the title will suffice)
  • create a relatedEntries Entries field, which has sources set to the blog channel
  • create a collection channel with an entry type that has the relatedEntries field in it added twice; the second instance should have the handle changed to moreRelatedEntries
  • create at least one blog entry
  • create at least one entry in the collection channel; leave the relatedEntries field empty; add a blog entry to the moreRelatedEntries field;
  • the template for the collection channel should contain the following code:
<h1>{{ entry.title }}</h1>

{% set relatedEntries = entry.relatedEntries.eagerly().all() %}
<p>relatedEntries:</p>
<ul>
    {% for item in relatedEntries %}
        <li>{{ item.title }}</li>
    {% endfor %}
</ul>
{% set moreRelatedEntries = entry.moreRelatedEntries.eagerly().all() %}
<p>moreRelatedEntries:</p>
<ul>
    {% for item in moreRelatedEntries %}
        <li>{{ item.title }}</li>
    {% endfor %}
</ul>
  • the collection entry added to the moreRelatedEntries shows up in both the moreRelatedEntries and relatedEntries field

  • if you only add an entry to the relatedEntries, it will only show for that field, and the moreRelatedEntries will be empty - as expected

  • if you add entries to both relatedEntries and moreRelatedEntries fields, the contents of both will show as expected

  • if you swap the order of the relatedEntries and moreRelatedEntries fields and then, in the collection entry, fill out only the relatedEntries field, leaving the moreRelatedEntries field empty, the moreRelatedEntries will incorrectly load the content of the relatedEntries field

@i-just i-just requested a review from brandonkelly January 14, 2025 10:38
@brandonkelly brandonkelly merged commit 38dc728 into 5.x Jan 14, 2025
@brandonkelly brandonkelly deleted the bugfix/16191-lazy-eager-loading-and-multi-instance-relation-field branch January 14, 2025 18:41
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.

2 participants