首页 > 解决方案 > Laravel Multi BelongsTo RelationShip Merge with Eager Loading

问题描述

Laravel 版本:7.0

reviews表 (Model - Review) 有id, product_type, product_id,rating列。

product_type可以是service, plugin,module并且每个值都有自己的模型App\Service, App\Plugin, App\Module. 我可以model names直接输入,product_type但我更喜欢使用这些值。这是Review模型关系。

public function plugin()
{
   return $this->belongsTo(Plugin::class, "product_id")->withDefault();
}
public function module()
{
   return $this->belongsTo(Module::class, "product_id")->withDefault();
}
public function service()
{
   return $this->belongsTo(Service::class, "product_id")->withDefault();
}

public function getItem()
{
   if($this->product_type=='module')
   {
      return $this->module;
   }elseif($this->product_type=='service')
   {
      return $this->service;
   }else {
      return $this->plugin;
   }
}

现在我想在 Review Model 中通过预先加载来获得它们,如下所示:

$reviews = Review::with("getItem")->get();

如果没有急切加载,我可以使用$review->getItem()->name// 这会返回产品名称。

如何通过急切加载获得它们?

标签: phplaraveleloquentpolymorphismlaravel-relations

解决方案


您可以轻松地将其实现为多态关系。在您的评论模型中,您可以这样做:

模型结构

应用\评论.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Review extends Model
{
    public function reviewable()
    {
        return $this->morphTo();
    }
}

然后将 reviews() 方法添加到您的App\ServiceApp\PluginApp\Module模型中

public function reviews()
{
    return $this->morphMany('App\Review', 'reviewable');
}

表结构

您的评论表可能如下所示:

reviews
    id - integer
    body - text
    reviewable_id - integer
    reviewable_type - string

注意reviewable_idreviewable_type字段。存储已审核项目的reviewable_idid 并reviewable_type存储与项目相关的模型。

检索关系

您可以通过模型访问关系。例如,要访问服务的所有评论,我们可以使用 reviews 动态属性:

$service = App\Service::find(1);

foreach ($service->reviews as $review) {
    //
}

您还可以通过访问执行 morphTo 调用的方法的名称,从多态模型中检索多态关系的所有者。在您的情况下,这是 Review 模型上的可审查方法。因此,我们将该方法作为动态属性访问:

$review = App\Review::find(1);

$reviewable = $review->reviewable; 

reviewable 将返回 Review 模型上的模型ServicePlugin或者Module


推荐阅读