Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

verona's avatar

Make custom query builder method (query scope) for all models in Laravel 5.5

I have multiple models, all with timestamps. I'm often using whereDate to get all rows from today and yesterday, like this:

ModelName::whereDate('created_at', now()->today())->get();
ModelName::whereDate('created_at', now()->yesterday())->get();

I want to have it shorter, simplier, like:

ModelName::today()->get();
ModelName::yesterday()->get();

I can not find any methods to do this, so I found in documentation that I can make own "scopes". The problem is, that I can make it for specified model, but I can not find a way to make it globally, for all models. Now I need to paste this scope methods in every model class. This works, but I need to repeat this code in every model class, so it's not a good way to do this I'm sure.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ModelName extends Model
{


    /**
     * Custom scope (query builder method) to easy return all items from today
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeToday($query)
    {
        return $query->whereDate('created_at', now()->today());
    }


    /**
     * Custom scope (query builder method) to easy return all items from yesterday
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeYesterday($query)
    {
        return $query->whereDate('created_at', now()->yesterday());
    }
}
0 likes
4 replies
lostdreamer_nl's avatar

Either that, or create a BaseModel class for your own models to extend instead of the default Eloquent one. If you ever have functionality that needs to be applied to all models, you can add it to your BaseModel.

ie:

// app\Models\BaseModel.php
abstract class BaseModel extends Model {
    public function scopeToday($query)
    {
        return $query->whereDate('created_at', now()->today());
    }
}

// app\Models\Category.php
Class Category extends BaseModel  {

}
// app\Models\User.php
Class User extends BaseModel  {
    use Authenticatable, Authorizable, CanResetPassword, Notifiable;

}

Having the BaseClass abstract makes sure you can never instantiate a BaseModel by itself.

3 likes
JohnDeRigo's avatar

@lostdreamer_nl I think that also you could use trait for this. it will be more flexible and dont have to make another class to extend.

1 like
Sairahcaz's avatar

I wrapped these scopes in a small package, cause I needed it in multiple projects:

https://github.com/laracraft-tech/laravel-useful-additions#fromtoday-fromyesterday

Install via composer:

composer require laracraft-tech/laravel-useful-additions

This is how it is working:

use LaracraftTech\LaravelUsefulAdditions\Traits\UsefulScopes;

$class = new class extends Model
{
    use UsefulScopes;

    protected $timestamps = true;
    protected $table = 'scope_tests';
};

$class->create(['foo' => 'foo1', 'bar' => 'bar1', 'quz' => 'quz1']);
$class->create(['foo' => 'foo2', 'bar' => 'bar2', 'quz' => 'quz2', 'created_at' => now()->yesterday()]);

$class::select('foo')->fromToday()->first()->toArray(); // return ['foo' => 'foo1']
$class::select('foo')->fromYesterday()->first()->toArray(); // return ['foo' => 'foo2']

Please or to participate in this conversation.