In my project I'm writing a method on one of my models that uses one of it's relationships and a sub-relationship so I am having to use lazy eager loading:
class MyModel extends Model
{
public function doSomething()
{
// Lazy eager load relationship and subrelationship
$this->load('relationship', 'relationship.subrelationship');
$relatedItems = $this->relationship;
foreach ($relatedItems as $relatedItem) {
$subrelatedItems = $relatedItem->subrelationship;
foreach ($subrelatedItems as $subrelatedItem) {
// Do something...
return true;
}
}
return false;
}
}
The Model::load()
method in Laravel can be used to re-load a relationship and does a new database query every time. Therefore, each time I call my method MyModel::doSomething()
, (Or call another method that uses similar relationships) another database query is executed.
I know that in Laravel you can call a relationship a number of times like this:
$relatedItems = $model->relationship;
$relatedItems = $model->relationship;
$relatedItems = $model->relationship;
$relatedItems = $model->relationship;
..and it doesn't repeat the query since it has already loaded the relationship.
I was wondering if it was possible to avoid querying the database every time I want to use my relationship inside the model? I had the idea that I could use $this->getRelations()
to work out which relationships had been loaded and then just skip them if they already had:
$toLoad = ['relationship', 'relationship.subrelationship'];
$relations = $this->getRelations();
foreach ($toLoad as $relationship) {
if (array_key_exists($relationship)) {
unset($toLoad[$relationship]);
}
}
if (count($toLoad) > 0) {
$this->load($toLoad);
}
That works to an extent, it's able to skip loading relationship
each time, but relationship.subrelationship
isn't actually stored in the array returned by $this->getRelations()
. I would imagine it is stored in the sub-model(s) as subrelationship
.
Cheers
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire