• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

XF 2.0 TO_MANY relation and templates

#1
Hello. I see very strange behaviour. I have entity 'MissionRecord' with TO_MANY relation to 'NpcMissionRecord', if try load this entity with relation using default finder
Code:
$this->finder('.../MissionRecord')
     ->with('NpcMissionRecord')
     ->where('id', $id)
     ->fetch();
i receive Exception: Joins only support TO_ONE relationships currently, so need make new code with using hydrateRelation
All fine here, system look great, just small limitation, no problem. I load another entities for TO_MANY relation without using ->with(...) in first finder, combine both sets with hydrateRelation. And then use this combined entities in tempate
Code:
<xf:foreach loop="$missions" value="$mission">
    ...
        <xf:if is="$mission.NpcMissionRecord is not empty">
            <xf:foreach loop="{$mission.NpcMissionRecord}" value="$missionNpcRecord">
                ...
            </xf:foreach>
        </xf:if>
    ...
</xf:foreach>

If i not load 'NpcMissionRecord' by php code, before move parameters to template, no relations as part of 'MissionRecord' entity in template, there should just no relation inside entity variable, at least dump inside tempate or php code return next
Code:
MissionRecord {#254 ▼
  -_uniqueEntityId: 5
  ...
  #_values: array:19 [▼
       ...
  ]
  #_relations: []
  ...
}

No relations without pre-load it inside php code. But right after use <xf:if is="$mission.NpcMissionRecord is not empty"> inside template, this relations write to entity, even if there wasn't pre-load. Right after use <xf:if is="$mission.NpcMissionRecord is not empty"> or just {{ $mission.NpcMissionRecord }} i have next
Code:
MissionRecord {#254 ▼
  -_uniqueEntityId: 5
  ...
  #_values: array:19 [▼
    ...
  ]
  #_relations: array:1 [▼
    "NpcMissionRecord" => ArrayCollection {#328 ▼
      #entities: array:1 [▼
        28 => NpcMissionRecord {#321 ▼
          -_uniqueEntityId: 62
         ...
          #_values: array:6 [▼
            ...
          ]
          ...
        }
      ]
      #populated: true
    }
  ]
  ...
}

Why xf load TO_MANY relation even when i no need it? Why i should use code what found in entities needed parameters, load another entities for with this parameters, combine both sets, while xf template can do it with a flick of the fingers? This is undocumented feature or manually limitation for developers?
Now i need think how for template hide no needed relations or another set of variables, becouse even if i just want check load i relations or not, relations become exist.

I confused.

Edit: This feature useful, this is not problem in general, but why it work?
 
Last edited:

DragonByte Tech

Well-known member
#2
Hello. I see very strange behaviour. I have entity 'MissionRecord' with TO_MANY relation to 'NpcMissionRecord', if try load this entity with relation using default finder
Code:
$this->finder('.../MissionRecord')
     ->with('NpcMissionRecord')
     ->where('id', $id)
     ->fetch();
i receive Exception: Joins only support TO_ONE relationships currently, so need make new code with using hydrateRelation
You don't actually need to do this, if you refer to the NpcMissionRecord normally, it'll get fetched.

Also, the way you're referencing the finder is not correct. Finders should be in the format XF:User or DBTech\Credits:Currency


Fillip
 
#3
So if just refer to relation it auto load if wasn't loaded before... Useful, but generate many database requests, if not pre-load before move variables to template

referencing the finder is not correct
Agree, wrong example. Not use it when trying make some similar
 
Last edited:

katsulynx

Well-known member
#4
You can't pre-fetch TO_MANY relations. I guess it's a problem with the underlying MySQL-Query. Being able to fetch rows with their TO_MANY relations would require additional processing at the fetch() stage to merge all received rows back into one entity (as you will receive one row from the database for each entity of the TO_MANY relation).

Either way, pre-loading is just for efficiency. All relations that were not pre-loaded can still be fetched at template compile time if needed. They will only be empty if they don't exist.
 
#5
You can't pre-fetch TO_MANY relations
Either way, pre-loading is just for efficiency
You have right, this is mysql query limit. You can't load 2+ lines joined to 1 line without duplicate this 1 line.

All fine here. I just was wonder that xf auto load related entities by relation name runtime. I thought it should return null, coz nothing was loaded myself, and made template based on it