【问题标题】:Laravel Multi BelongsTo RelationShip Merge with Eager LoadingLaravel Multi BelongsTo RelationShip Merge with Eager Loading
【发布时间】:2020-11-09 05:19:54
【问题描述】:

Laravel 版本:7.0

reviews 表(模型 - 审查)具有 idproduct_typeproduct_idrating 列。

product_type 可以是servicepluginmodule,每个值都有自己的模型App\ServiceApp\PluginApp\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();

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

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

【问题讨论】:

    标签: php laravel eloquent polymorphism laravel-relations


    【解决方案1】:

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

    模型结构

    App\Review.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_id 存储已审核项目的 id,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 模型上的模型 ServicePluginModule

    【讨论】:

    • 谢谢,刚刚更改了我的表格列。但是,如何进行急切加载?我试过$review = Review::with("reviewable")-&gt;get(),但出现N+1 查询问题。有什么建议吗?
    • 这可以帮助Review::with('reviewable')-&gt;get()-&gt;loadMorph('reviewable', [Service::class =&gt; 'service', Plugin::class =&gt; 'plugin', Module::class =&gt; 'module']);
    猜你喜欢
    • 2019-10-20
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 2020-05-23
    相关资源
    最近更新 更多