Laravel Eloquent 查询具有 3 个级别的关系

Laravel Eloquent query relations with 3 levels

我需要一些关于 Laravel Eloquent

的查询帮助

我的申请中有 4 个模型

物品型号

class Item extends Model
{
    use HasFactory;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
       'code', 'name', 'type', 'price', 'cost', 'reorder_level', 'status'
    ];


    public function grnoteitems()
    {
        return $this->hasMany(Grnoteitem::class);
    }
}

Grnote 型号

class Grnote extends Model
{
    use HasFactory;

    protected $fillable = [
        'date', 'number', 'warehouse_id','user_id', 'authorized_id', 'approved_id', 'notes'
    ];

    public function grnoteitems()
    {
        return $this->hasMany(Grnoteitem::class);
    }

    public function warehouse()
    {
        return $this->belongsTo(Warehouse::class);
    }
}

Grnoteitem 型号

class Grnoteitem extends Model
{
    use HasFactory;

    protected $fillable = [
        'grnote_id', 'item_id', 'description', 'packing', 'quantity', 'price', 'total'
    ];

    public function grnote()
    {
        return $this->belongsTo(Grnote::class);
    }

    public function item()
    {
        return $this->belongsTo(Item::class);
    }
}

仓库模型

class Warehouse extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'address'];

    public function grnotes()
    {
        return $this->hasMany(Grnote::class);
    }
}

项目的数量是通过将 grnotes 中的数量和包装列相乘计算得出的 table。

现在我想从特定仓库检索所有项目及其数量(数量 * 包装)。

我厌倦了下面的查询


$items = Item::withSum('grnoteitems',  'quantity', function($query) use($warehouse, $from, $to){

            $query->with('grnote', function($query1) use($warehouse, $from, $to){
                  $query1->where('warehouse_id', $warehouse->id)
                        ->whereBetween('date', [$from, $to])->get();
                    })->get();
            })->get();

这工作正常。但是我找不到任何方法来获得两个相乘列的总和

我想要类似的东西

$items = Item::withSum('grnoteitems', '(quantity * packing)', function($query) use($warehouse, $from, $to){

            $query->with('grnote', function($query1) use($warehouse, $from, $to){
                  $query1->where('warehouse_id', $warehouse->id)
                        ->whereBetween('date', [$from, $to])->get();
                    })->get();
            })->get();

请帮我解决这个问题。

写完所有的代码有点长,但我的想法是:

  • 从您需要的仓库开始查询
  • so Warehouse::first() [with grnote [with item]] 和 custom where stuff
  • 那么你需要计算的数据在Item和Grnote之间的枢轴table上,所以我会在两个关系中添加withPivot
  • 在此查询顺序中,枢轴值将作为与 Item 对象的关系附加
  • 我将向项目模型添加一个新属性。检查是否设置了 pivot 属性(因此它来自带有 pivot 的查询),计算数量,并将其附加到 Item 实例

您还可以在生成的集合上循环以附加您的新属性。