2015-12-02 138 views
1

我有以下设置为我的雄辩型号/ DB关系:查询雄辩关系

Student有许多PhdReport

PhdReport有一个Link

我需要得到Student为什么会产生(单)最近PhdReport(由属性date_to)是6个月以上和连接到所述PhdReport具有Link“完整”的status

我试图做到这一点使用雄辩的关系,我是很新,查询的关系,所以我想知道是否有到一个我正在一个更好的办法的概念。

下面是相关的代码至今:

PhdReport.php

public function link() 
{ 
    return $this->belongsTo(\App\Models\Link::class); 
} 

Student.php

public function phdReport() 
{ 
    return $this->hasMany(\App\Models\PhdReport::class); 
} 

public function latestPhdReport() 
{ 
    return $this->hasOne(\App\Models\PhdReport::class)->latest('date_to'); 
} 

/* this doesn't work! */  
public function lastPhdReportSixMonthsAgo() 
{ 
    $sixMonthsAgo = \Carbon\Carbon::now()->subMonth(6); 

    return $this->whereHas('latestPhdReport', function ($query) use ($sixMonthsAgo) { 
     $query->where('date_to', '<=', $sixMonthsAgo); 
    }); 
} 

这是我最好的拍摄,但迄今为止我我不确定第一个whereHas是否适用于第二个whereHas a LSO?

$sixMonthsAgo = \Carbon\Carbon::now()->subMonth(6); 

$students = $this->student 
    ->whereHas('phdReport.link', function ($query) { 
     $query->where('status', 'complete'); 
    }) 
    ->whereHas('latestPhdReport', function ($query) use ($sixMonthsAgo) { 
     $query->where('date_to', '<=', $sixMonthsAgo); 
    }) 
    ->get(); 

如果我运行:

$students = $this->student 
    ->has('lastPhdReportSixMonthsAgo') 
    ->get(); 

我得到:

BadMethodCallException in Builder.php line 1994: 
Call to undefined method Illuminate\Database\Query\Builder::getRelated() 

任何建议,将不胜感激!

+0

这将做http://softonsofa.com/querying-relations-in-laravel-get-models-where-latest-相关 - 是/ –

+0

@JarekTkaczyk感谢您的链接。我现在有一个工作解决方案,但它肯定需要一些微调。一旦我满意,我会发布一个答案。再次感谢您的帮助 - 非常感谢。 – haakym

+1

很酷。完成后分享您的代码。 –

回答

0

这是我目前的解决方案,我还没有来得及重构,但是我敢肯定,它可以通过做只能查询并没有过滤得到改善。当我得到时间的时候会编辑,但是我认为我会放弃它,因为它可能会帮助别人。大部分信贷@JarekTkaczyk

$monthsAgo = \Carbon\Carbon::now()->subMonth($months); 

// Query 1: students with a completed report 
$studentsWithCompletedLink = $studentsWithCompletedLink 
    ->whereHas('phdReport.link', function ($query) { 
     $query->where('status', 'complete'); 
    }) 
    ->get(); 

if ($months != 0) { 
    // filter through to get students where the report date_to is more than $months months ago 
    $studentsWithReport = $studentsWithCompletedLink->filter(function ($student) use ($monthsAgo) { 
     return $student->latestReport->date_to <= $monthsAgo; 
    }); 
} 

Student.php

public function latestPhdReport() 
{ 
    return $this->hasOne(\App\Models\PhdReport::class)->latest('date_to'); 
}