在OR上下文中使用多个Laravel范围

时间:2017-05-21 15:07:25

标签: php laravel eloquent

我的订阅模型在我的Laravel应用中包含start_dateend_date属性。我创建了两个查询范围scopeActive和scopeFuture来分别查找活动和未来订阅。

我想知道如何使用OR上下文中的两个范围构建查询,以便我可以找到任何有效或未来的订阅。

订阅模式

/**
 * Scope a query to only include active subscriptions.
 *
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeActive($query)
{
    return $query->where('start_date', '<', Carbon::now())
                 ->where('end_date', '>', Carbon::now());
}

/**
 * Scope a query to only include future subscriptions.
 *
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeFuture($query)
{
    return $query->where('start_date', '>', Carbon::now());
}


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

商业模式

.....
public function subscriptions()
{
    return $this->hasMany('App\Subscription');
}

用户模型

public function business()
{
    return $this->hasOne('App\Business');
}

控制器

Subscription::active()->get();

4 个答案:

答案 0 :(得分:3)

试试这个。

$subscriptions = Subscription::where(function ($query) {
    $query->active();
})->orWhere(function ($query) {
    $query->future();
})->get();

编辑:评论中要求的示例

$subscriptions = auth()->user()
    ->business()
    ->subscriptions()
    ->where(function ($query) {
        $query->active();
    })->orWhere(function ($query) {
        $query->future();
    })->get();

答案 1 :(得分:2)

Subscription::active()->orWhere( function($q){
            return $q->future() ;
        } )->get() ;

答案 2 :(得分:0)

我不是要回答,只是想举一个例子。

public function scopeVisable(Builder $builder){

    $builder->where(function($builder){
            $builder->orWhere(function($builder){
            $builder->isPublic();
        });
        $builder->orWhere(function($builder){
            $builder->isMine();
        });
    });

    return $builder;
}

public function scopeIsPublic(Builder $builder){

    $builder->whereIsPublic(true);

    return $builder;
}

public function scopeIsMine(Builder $builder){

    $user = app(CurrentUser::class);
    $builder->whereAddedByUserId($user->getKey());

    return $builder;
}

生成器的-> toSql()显示:

select * from channels where (('is_public' = ?) or ('added_by_user_id' = ?))

答案 3 :(得分:0)

利用参数。您可以尝试类似...

public function scopeCanceled($query, $scope = 'where')
{
    return $query->$scope('canceled_at');
}

然后您可以执行例如$query->canceled('orWhere')

然后您可以使用以下方法消除丑陋状态:

public function scopeOrCanceled($query)
{
    return $this->scopeCanceled($query, 'orWhere');
}

示例$query->orCanceled()

通常在范围内,我发现总是具有某种可选值以使事情变得灵活

public function scopeApproved($query, bool $value = true)
{
    return $query->where('is_approved', $value);
}

为此用例添加第三个参数便有意义

public function scopeApproved($query, string $scope = 'where', bool $value = true) {
    return $query->$scope('is_approved', $value);
}