首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Laravel Scopes on DB Builder

Laravel Scopes on DB Builder
EN

Stack Overflow用户
提问于 2020-06-11 18:38:48
回答 1查看 82关注 0票数 0

我完全知道Eloquent上的查询作用域,它工作得很好。我的问题有点不同,这一次我在DB query Builder上有一个查询,其中包含一些在其他模型上重复的条件,所以我想提取和重用这些条件。这是我最初的查询:

代码语言:javascript
复制
$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

代码语言:javascript
复制
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);
            });
        });
}

为了像这样重用作用域:

代码语言:javascript
复制
$grants = $this->grants()
        ->grantsActive()
        ->get();

请注意,$this->grants()是一种关系:

代码语言:javascript
复制
public function grants()
{
    return $this->hasMany(Grant::class)
}

我知道Scopes使用Eloquent可以很好地工作,但我不能使用DB Builder。有什么想法吗?

提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2020-06-11 20:39:46

我认为我过度设计了这种代码重构,试图以"Laravel“的方式来做事情。这没有错,我喜欢这个框架,如果对我有意义的话,我喜欢遵循它的建议。在我看来,望远镜是相当酷的。

我使用一个常规函数来返回包含我需要的所有条件的闭包,从而解决了这个问题:

代码语言:javascript
复制
   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);
                });
       };
   }

然后:

代码语言:javascript
复制
$this->grants()
        ->where($this->grantsUpTo($date))
        ->get();

我对这个解决方案很满意,如果有人有更好的想法,请分享。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62322467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档