Laravel Eloquent深层嵌套查询

时间:2018-03-12 03:02:00

标签: php laravel laravel-eloquent nested-query

我还在学习Laravel,但我找不到解决这个问题的方法。 我需要获得与特定合作伙伴类型相关的发票(有费用)。

我试过了:

$p = Project::with(['invoices.partner.partnerType' => function($query){
            $query->where('partnerTypeName', 'Lieferant');
        }, 'expenses'
    ])->where('id', $id)
      ->first();

我想为Lieferant选择发票,但我会收到一个项目的所有发票。

项目模型:

public function invoices()
{
    return $this->hasMany('App\Invoice');
}

发票模型

public function expenses()
{
    return $this->hasMany('App\Expense');
}
public function partner()
{
    return $this->belongsTo('App\Partner');
}

合作伙伴模型

public function partnerType()
{
    return $this->belongsTo('App\PartnerType');
}

编辑:PartnerType模型

public function partners()
{
    return $this->hasMany('App\Partner');
}

编辑2:数据库

Partner(partnerID, name, partnerTypeId)
PartnerType(partnerTypeId, partnerTypeName)
Project(projectID, name)
Invoice(invoiceID, name, projectID, partnerID)
Expenses(expenseID, invoiceID)

2 个答案:

答案 0 :(得分:0)

如果你的模特看起来那样。 应该像:

$p = Project::with(['invoices' => function($query){
            $query->where('partnerTypeName', 'Lieferant')
                  ->with(['expenses','partner' => function($q){
                        $q->with('partnerType');
                    }]);
        }])->where('id', $id)
      ->first();

 return dd($p);

答案 1 :(得分:0)

您的问题的解决方案是更新您的查询:

$p = Project::with(['invoices' => function($query){
        $query->with('expenses')->whereHas('partner.partnerType', function($q){
            $q->where('partnerTypeName', 'Lieferant');
        });
     }])
     ->where('id', $id)
     ->first();

但更清洁的解决方案是使用scope解决您的问题。

在您的发票模型中。

// Invoice.php
public function scopeByPartnerType($query, $partnerType)
{
    $query->whereHas('partner.partnerType', function($q) use ($partnerType) {
        $q->where('partnerTypeName', $partnerType);
    });
}

然后在您的项目模型中添加另一个只会获得特定合作伙伴类型的发票的关系。

// Project.php
public function lieferantInvoices()
{
    return $this->hasMany('App\Invoices')->byPartnerType('Lieferant');
}

现在你可以做到这一点:

$project->find($id)->load('lieferantInvoices');
相关问题