在我的应用中,我有一堵墙,上面贴满了帖子。
每个帖子都可以包含附件,例如Video
或Product
(以及许多其他类型,因此为每种类型建立单独的关系将是一个坏主意)。
这是数据库结构示例:
videos
id
...
products
id
...
product_photos
product_id
...
posts
id
...
post_attachments
post_id
attachment_id
attachment_type
在Post
模型中,我定义了与PostAttachment
的关系:
class Post extends Model
{
public function attachments()
{
$this->hasMany(PostAttachment::class);
}
}
在PostAttachment
模型中,我定义了与附件的多态关系:
class PostAttachment extends Model
{
public function attachment()
{
return $this->morphTo();
}
}
如果我想弄满整个墙,我可以做这样的事情:
$posts = Post::with([
'attachments',
'attachments.attachment'
])->get();
结果为:
[
{
"id": 1,
...
"attachments": [
{
...
"attachment_type": "App\Models\Video",
"attachment": {
"id": 101,
...
}
},
{
...
"attachment_type": "App\Models\Product",
"attachment": {
"id": 203,
...
}
},
]
}
]
但是,如果我想在结果中包含Product
张照片怎么办?
我不能做这样的事情:
$posts = Post::with([
'attachments',
'attachments.attachment',
'attachments.attachment.photos'
])->get();
因为photos
关系仅存在于Product
模型中,而不存在于Video
中。
肮脏的解决方案是在模型定义中包括关系加载:
class Product
{
protected $with = [
'photos'
];
...
}
但是通过这种解决方案,即使我直接获得Product
模型,照片也将被退回。
仅在显示墙时如何加载Product
张照片?
在此先感谢您,我的英语不好。
答案 0 :(得分:0)
如果您使用的是 Laravel 5.8.22或更高版本,则可以使用 嵌套急切加载morphTo关系 。`
use Illuminate\Database\Eloquent\Relations\MorphTo;
$posts = Post::query;
$posts = $posts->with([
'attachments.attachment' => function (MorphTo $morphTo) {
$morphTo->morphWith([
Product::class => ['photos'],
//add more if any
]);
}]);
$posts = $posts->get();