使用范围的Laravel集合过滤器

时间:2020-07-15 09:39:00

标签: laravel eloquent

我有下表:

有效

id 开始于 结尾_p

我想每天获取所有活动数据,比较两个日期starts_at和ends_at并以天为单位获取差异,例如以下示例:

Route::get('test', function(){
$dailyActives = \App\Models\Active::all()->filter(function ($active) {
   return $active->starts_at->diffInDays($active->ends_at) >= 1 && $active->starts_at->diffInDays($active->ends_at) <= 3;
});

dd($dailyActives);

});

它可以100%工作。

但是我想重用这段代码,因为我有更多的模式,例如每日,每周,每月。

我的想法是在模型中创建范围,但是我不能使用过滤器,因为$ query不是集合。 我尝试了以下代码:

/**
 * Scope a query to only include daily actives.
 *
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeDaily($query)
{
    $query->filter(function ($active) {
        if($active->starts_at->diffInDays($active->ends_at) >= 1 && $active->starts_at->diffInDays($active->ends_at) <=3) {
            return true;
        }
    });
}

那么有人可以推荐我最好的方法吗?也许使用范围以及如何?或创建一个可重用的类,例如,仅调用Active :: daily()-> get(),例如,我每天都会获取所有活动对象。

非常感谢!

1 个答案:

答案 0 :(得分:1)

您不需要使用过滤器。像这样$dailyActives = \App\Models\Active::interval('weekly')->get();

public function scopeInterval($query, $interval = 'daily')
{
    // daily
    $dateBetween = [now()->startOfDay(), now()->endOfDay()];

    if($interval === 'weekly'){
        $dateBetween = [now()->startOfWeek(), now()->endOfWeek()];
    }
    elseif($interval === 'month'){
        $dateBetween = [now()->startOfMonth(), now()->endOfMonth()];
    }

    $query->whereBetween('created_at', $dateBetween);
    
    return $query;
}