Craft CMS Asked by Myles Hyson on February 19, 2021
So I have structures that are related in the follwing way:
I know that I can eager load all Locations with related Providers and Health Topics very easily using using something like this:
craft.entries.section('locations').with(['providers.healthTopics']).all()
However how can I eager load the reverse relationship, loading all Health Topics with their related Providers and Locations? The eager loading function seems to go from parent to children but not from children to parent…though I could be missing something there?
Ok so here's how I ended up doing this. Essentially querying everything and adding a sourceId
and targetId
property to each result. In order to get this query to work though, we need to add a behavior to the Entry component to support two new properties, sourceId
and targetId
.
// This basically left-joins the the relationship table to our sections. This allows us
// to essentially "eager-load" in reverse.
$relatedQuery = Entry::find()
->section(['healthTopics', 'providers', 'locations'])
->addSelect('relations.targetId')
->addSelect('relations.sourceId')
// You can query to get the field ids here, I just decided to look them up in the db.
->leftJoin(
'{{%relations}} relations' ,
'([[elements.id]] = [[relations.sourceId]]) AND ([[relations.fieldId]] = 2 OR [[relations.fieldId]] = 5)'
)
->groupBy('elements.id')
->all();
// Same thing here, just looked up the section ids instead of querying for them.
$healthTopics = ArrayHelper::where($relatedQuery, 'sectionId', '1');
$providers = ArrayHelper::where($relatedQuery, 'sectionId', '3');
$locations = ArrayHelper::where($relatedQuery, 'sectionId', '2');
Next, I needed to add a behavior to the Entry component so that it could support having the two new properties we added, sourceId
and targetId
.
<?php
namespace foobehaviors;
use yiibaseBehavior;
class EntryBehavior extends Behavior
{
public $targetId;
public $sourceId;
}
Event::on(Entry::class, Entry::EVENT_DEFINE_BEHAVIORS, static function (DefineBehaviorsEvent $event) {
$event->behaviors['entryBehavior'] = ['class' => EntryBehavior::class];
});
Correct answer by Myles Hyson on February 19, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP