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

RomainB's avatar
Level 13

use firstOrCreate with whereRaw to compare date?

Hi. I'm adding stats functionality on a list which display providers to my visitors to know how much it has been displayed.

I want to detail the stats for each week, so I want to create a new entry in database every week if it doesn't exist.

First, I used this logic:

$stats = ProviderStats::firstOrCreate(['provider_id' => $event->provider->id]);
if($stats->created_at->weekOfYear != Carbon::now()->weekOfYear)
    $stats = $event->provider->stats()->create();
$stats->increment('phone_displayed');
$stats->save();

It works But it create two ProviderStat in memory, and one is useless. Also I asked myself: "Is there a way to do it more fluently?". I know (for now) it's not possible to compare date in the firstOrCreate attributes comparison. So I tried to use whereRaw to do this:

firstOrCreate(['provider_id' => $event->provider->id])->whereRaw('WEEK(`created_at`) = '. Carbon::now()->weekOfYear)

But... It doesn't work :( the whereRaw is simply ignored!

I thinked: maybe I should create a "freshOrCreate" method? Or is there a way to compare date in firstOrCreateMethod?

Thanks for any suggestions.

[EDIT] Finally I can use fluent where and whereRaw directly into my event. The problem was the WEEK() SQL function which is different from Carbon::weekOfYear . I'm using WEEKOFDAY() SQL function and it's working.

For now I extended Model class with an abstract class Stat, which is implemented by my ProviderStat class, I still welcome any suggestions/agreements:

abstract class Stat extends Model
{
    public static function boot()
    {
        parent::boot();
    }
    /**
     * Get the first fresh(same week) record matching the attributes or create it.
     *
     * @param  array  $attributes
     * @return static
     */
    public static function freshOrCreate(array $attributes)
    {
        if ( ! is_null($instance = static::where($attributes)->whereRaw('WEEKOFYEAR(`created_at`) = '. Carbon::now()->weekOfYear .' AND YEAR(`created_at`) = ' . Carbon::now()->year)->first()))
        {
            return $instance;
        }

        return static::create($attributes);
    }
}
0 likes
0 replies

Please or to participate in this conversation.