desancheztorres
desancheztorres

Reputation: 363

Laravel collection filter using scopes

I have the following table:

Active

id starts_at ends_at

I would like to get all the actives daily, comparing the two dates starts_at and ends_at and get the diff in days, like this example:

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);

});

it works 100%.

But I would like to reuse this code as I have more modes like Daily, Weekly, Month.

My idea was creating a scope in the model but I can't use filter as $query is not a collection. I tried the following code:

/**
 * 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;
        }
    });
}

So can someone recommend me the best way to do that? Maybe using scope and how? or creating a reusable class, where just calling the Active::daily()->get() I get all the actives daily, for example.

Many thanks in advance!

Upvotes: 0

Views: 1171

Answers (1)

Kongulov
Kongulov

Reputation: 1171

You do not need to use a filter. Use scop like this $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;
}

Upvotes: 1

Related Questions