我完全知道Eloquent上的查询作用域,它工作得很好。我的问题有点不同,这一次我在DB query Builder上有一个查询,其中包含一些在其他模型上重复的条件,所以我想提取和重用这些条件。这是我最初的查询:
$grants = $this->grants()
->where(function ($query) use ($date) {
$query->whereDate('grant_date', '<=', $date)
->where(function ($query) use ($date) {
$query->whereNull('canceled')
->whereNull('cost');
})
->orWhere(function ($query) use ($date) {
$query->whereDate('canceled', '>', $date);
});
})
->get();所以我的想法是创建一个作用域,为了这个例子,让我们调用ActiveGrants:
public function scopeActiveGrants($query, $date)
{
return $query->where(function ($query) use ($date) {
$query->whereDate('grant_date', '<=', $date)
->where(function ($query) use ($date) {
$query->whereNull('canceled')
->whereNull('cost');
})
->orWhere(function ($query) use ($date) {
$query->whereDate('canceled', '>', $date);
});
});
}为了像这样重用作用域:
$grants = $this->grants()
->grantsActive()
->get();请注意,$this->grants()是一种关系:
public function grants()
{
return $this->hasMany(Grant::class)
}我知道Scopes使用Eloquent可以很好地工作,但我不能使用DB Builder。有什么想法吗?
提前谢谢。
发布于 2020-06-11 20:39:46
我认为我过度设计了这种代码重构,试图以"Laravel“的方式来做事情。这没有错,我喜欢这个框架,如果对我有意义的话,我喜欢遵循它的建议。在我看来,望远镜是相当酷的。
我使用一个常规函数来返回包含我需要的所有条件的闭包,从而解决了这个问题:
public function activeGrants($date): Closure
{
return function ($query) use ($date) {
$query->whereDate('grant_date', '<=', $date)
->where(function ($query) use ($date) {
$query->whereNull('cancel')
->whereNull('cost');
})
->orWhere(function ($query) use ($date) {
$query->whereDate('cancel', '>', $date);
});
};
}然后:
$this->grants()
->where($this->grantsUpTo($date))
->get();我对这个解决方案很满意,如果有人有更好的想法,请分享。
https://stackoverflow.com/questions/62322467
复制相似问题