I have a cronjob in Laravel scheduled to update some info in a table once a day. That job just call a function and that function try to update the table. What is happening is that when the information is updated, the column request_at is updated with the same info as updated_at, but only the columns updated_at and status_id should be changed
Here's my model, the migration and the function called by the cronjob
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
class StockRecharge extends Model
{
use SoftDeletes;
protected $fillable = [
'worker_stock_id',
'status_id',
'requested_at'
];
protected $casts = [
'worker_stock_id' => 'integer',
'status_id' => 'integer',
'requested_at' => 'datetime'
];
/**
* Return the related status
* @return HasOne
*/
public function status(): HasOne
{
return $this->hasOne(Status::class);
}
/**
* Return the related worker stock
* @return BelongsTo
*/
public function workerStock(): BelongsTo
{
return $this->belongsTo(WorkerStock::class);
}
}
migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateStockRecharges extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('stock_recharges', function (Blueprint $table) {
$table->id();
$table->foreignId('worker_stock_id')->constrained('worker_stocks')->cascadeOnDelete()->cascadeOnUpdate();
$table->tinyInteger('status_id', false, true);
$table->timestampTz('requested_at');
$table->timestampsTz();
$table->softDeletesTz();
$table->foreign('status_id')->references('id')->on('statuses')->cascadeOnDelete()->cascadeOnUpdate();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('stock_recharges');
}
}
cronjob
private static function updateStockRechargeToExpiring(): bool
{
Log::info('starting updateStockRechargeToExpiring()');
try {
StockRecharge::whereNull('deleted_at')
->where('status_id', StatusRepository::getByName('ACTIVE'))
->whereRaw('DATEDIFF(CURDATE(), requested_at) = 4')
->update(['status_id' => StatusRepository::getByName('EXPIRING')]);
} catch (\Throwable) {
Log::error('status update failed on updateStockRechargeToExpiring()');
return false;
}
Log::info('job updateStockRechargeToExpiring() finished successfully');
return true;
}
I've used the the function DB::enableQueryLog() to see exactly what was the query and got the following:
array:2 [
0 => array:3 [
"query" => "select `id` from `statuses` where (`name` = ?)"
"bindings" => array:1 [
0 => "EXPIRING"
]
"time" => 4.92
]
1 => array:3 [
"query" => "update `stock_recharges` set `status_id` = ?, `updated_at` = ? where `deleted_at` is null and DATEDIFF(CURDATE(), requested_at) = 4"
"bindings" => array:2 [
0 => 3
1 => "2024-03-19 12:27:32"
]
"time" => 0.76
]
]
As we can see, there's no mention of request_at in the query, but it is changed anyway.
I've tried using DB::table('stock_recharges') instead of the model StockRecharge, but the result was the same
Laravel 9.52 MySQL 8.0.31
Has anyone faced something like it before?
Try
I think it is a conflict because you defined
requesed_atwhile you are searching withwhereRaw