【问题标题】:Eager loading polymorfic relation's related model渴望加载多态关系相关模型
【发布时间】:2019-11-11 06:57:10
【问题描述】:

在我的应用程序中,我有一堵墙。

每个帖子都可以有附件,例如 VideoProduct(以及许多其他类型,因此为每种类型创建单独的关系将是一个坏主意)。

这是数据库结构示例:

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的照片?

在此先感谢您,并为我的英语不好感到抱歉。

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    如果您使用的是 Laravel 5.8.22 或更高版本,您可以使用 Nested Eager Loading morphTo 关系。`

    docuemntation

    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();
    

    【讨论】:

    • 非常感谢!之前好像看过旧文档,所以没找到这个
    猜你喜欢
    • 2014-12-30
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-12
    • 2019-06-19
    相关资源
    最近更新 更多