PHP: 8.2
Laravel Framework: 11
MySQL
We have roughly the following code on our website to represent the overall problem.
Post.php
class Post extends BaseModel
{
public function blocks(): MorphMany
{
return $this->morphMany(Block::class, 'blockable');
}
}
Block.php
class Block extends Model
{
public function blockable(): MorphTo
{
return $this->morphTo();
}
public function alt(): string
{
$alt = '';
if ($this->caption) {
$alt = $this->caption;
} else if ($this->blockable->title) {
$alt = 'Block from ' . $this->blockable->title;
}
return $alt;
}
}
PostController.php
$posts = Post::where('status_id', 1)
->with('blocks')
->get();
This code works correctly and returns the expected result. But by calling $this->blockable within the alt function, it produces extra (duplicate) MySQL queries to find the parent, even though it is already queried and present. Is there a way to let Laravel know that blockable has already been queried as the parent?
One quick solution we found was the following, but we feel there is a more eloquent way of achieving this.
public function alt(Post $blockable): string
{
$alt = '';
if ($this->caption) {
$alt = $this->caption;
} else if ($blockable->title) {
$alt = 'Block from ' . $blockable->title;
}
return $alt;
}