Laravel枢轴模型与另一个表的关系

时间:2020-09-21 09:44:38

标签: laravel eloquent-relationship

enter image description here

数据库说明:

  • 物品有很多层
  • 层只有一种类型(大小,选项或附件)
  • 类型与选项具有多对多关系
  • optionType具有多种尺寸和价格

问题: 在雄辩的查询中,我能够获取数据直到option_type,我不知道如何创建option_type数据透视模型与大小模型的关系。

口才查询:

$items = Item::with(['tiers' => function ($query) {
            $query->with(['type' => function($query) {
                $query->with('sizes')
                    ->with('options')
                    ->with('addons');
            }]);
        }])->where('id', 1)->get();
        return $items;

我想要实现的目标: 我想急于加载带有大小的option_type,对于每个optiontype行,我可能都有大小及其价格。

问题: 当我编写查询时:

$query->with(['options' => function($query) {
    $query->with('sizes);
}])

基本上说选项与大小有关系,这是不对的,应该是optionType与大小有关系。我如何获取数据,以便显示每个optiontype_id,size_id和价格的记录。

类型模型:

class Type extends Model
{
    protected $table = 'types';

    public function options()
    {
        return $this->belongsToMany(Option::class);
    }
}

选项模型:

class Option extends Model
{
    public function type()
    {
        return $this->belongsToMany(Type::class);
    }
}

选项类型模型:

use Illuminate\Database\Eloquent\Relations\Pivot;

class OptionType extends Pivot
{
    protected $table = 'option_type';

    public function optiontypesize()
    {
        return $this->belongsToMany(Size::class, 'option_type_size', 'size_id', 'option_type_id');
    }
}

尺寸模型:

class Size extends Model
{
    public function optiontypesize()
    {
        return $this->belongsToMany(OptionType::class, 'option_type_size', 'size_id', 'option_type_id');
    }
}

1 个答案:

答案 0 :(得分:0)

我自己已经解决了这个问题,如果将来有人遇到相同的问题,我会在这里写下详细的答案。

我已经修改了数据库,但是问题的概念仍然相同。

enter image description here

说明:

  • 物品有很多层次
  • 层只有一种类型
  • 层具有许多选项,而选项具有许多层(使 场景中的option_tier表)
  • option_tier有很多大小,而大小有很多option_tier(带来 场景中的option_tier_price表,附加字段为 '价格')

解决方案: 我正在使用AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait来渴望加载枢纽关系。 该概念摘自本文https://medium.com/@ajcastro29/laravel-eloquent-eager-load-pivot-relations-dba579f3fd3a 唯一的区别是我已将关系从belongTo更改为hasMany,它的工作原理就像是一种魅力。

层模型:

use AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait;

class Tier extends Model
{
    use EagerLoadPivotTrait;
    protected $table = 'tiers';

    public function options()
    {
        return $this->belongsToMany(Option::class, 'option_tier')
            ->using(OptionTier::class)
            ->withPivot('id');
    }
}

选项模型:

use AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait;

class Option extends Model
{
    use EagerLoadPivotTrait;

    protected $table = 'options';
    
    public function tiers()
    {
        return $this->belongsToMany(Tier::class, 'option_tier');
    }
}

OptionTier模型:

use AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait;
use Illuminate\Database\Eloquent\Relations\Pivot;

class OptionTier extends Pivot
{
    use EagerLoadPivotTrait;
    
    protected $table = 'option_tier';
    
    public function price()
    {
        return $this->hasMany(OptionTierPrice::class, 'option_tier_id');
    }
}

OptionTierPrice模型:

use AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait;

class OptionTierPrice extends Model
{
    use EagerLoadPivotTrait;
    
    protected $table = 'option_tier_price';
    
    public function size()
    {
        return $this->belongsTo(Size::class);
    }
}

控制器:

$tiers = Product::with(['tiers' => function($query) {
    $query->with(['type'])
          ->with(['sizes'])
          ->with(['options.pivot.price.size'])
          ->with(['addons.pivot.price.size']);
}])
->get();
return $tiers;