Home > OS >  Laravel retrieve all records 20 mins from created_at time
Laravel retrieve all records 20 mins from created_at time

Time:07-05

I have a command which needs to send an email to a user 20 mins after their record was created.

The command runs every minute through the Kernel.php

$allUsers = User::where('created_at' = now()->addMinutes(20))

The above doesnt seem to return any records.

Any help would be greatly appreciated.

CodePudding user response:

The best approach on this is to create a Job queue for sending an email then use delayed-dispatching

You can dispatch the job upon record creation or through event listener by adding something like below after record creation

ProcessEmail::dispatch($user)->delay(now()->addMinutes(20));

Here's the full steps first run jobs migration php artisan queue:table

then run artisan command to create a job php artisan make:job ProcessEmail

then on your App/Jobs/ProcessEmail.php should have something like this

namespace App\Jobs;
///..uses here 


class ProcessEmail implements  ShouldQueue {
    //additional uses blablaba

    protected $user;
    public $tries = 3;

    
    public function __construct( $user ) {
        //assign the user as job property to access on handle
        $this->user = $user;
    }


    public function handle() {
    
        // Email proccess
        try {
            //However you run the email
            \Log::info('I run for user '. $this->user->email);
        } catch (\Throwable $exception) {     
            
            // re-attempt on failure
            if ($this->attempts() > 2) {

                // manually set the job as failed on 3rd attempt and throw some error
                throw $exception;
            }

            // release after 5 seconds to retry the job.
            $this->release(5);

            return;
        }
        
    }
    

    public function failed(\Throwable $e) {
        // Do something on failure
        \Log::info(  $e->getMessage()  );
    }

}

then whereever you create the record, call that jobs use App\Jobs\ProcessEmail;

then on your record creation, dispatch it after user is created like below

$user = User::create(['.......']);
ProcessEmail::dispatch($user)->delay(now()->addMinutes(20));

CodePudding user response:

hope this helps

    $startDate = Carbon::now()->subMinutes(21);
    $endDate = Carbon::now()->subMinutes(19);

    $allUsers = User::->whereBetween('created_at', [$startDate, $endDate])->get();

CodePudding user response:

In you query = sign only get record which exactly match with created_at. For example you create a record on date 25-06-2022 time 04:15:33.

As your command execute every minute so it will execute on 04:15:00 & 04:16:00, these will get only records that match with time and your created record is between these as seconds are not matching therefore it will return Null/empty. To access records you must use greater-than or equal sign >= in your query to get any record which is created before 20 minutes.

     $allUsers = User::where('created_at' >= now()->addMinutes(20))

Use some flag to keep record of users already sent email otherwise your code will send email to all users created before 20 minutes either email already sent or not.

  • Related