使用 Laravel Eloquent 更新表时发生不需要的列更改

问题描述 投票:0回答:1

我在 Laravel 中有一个 cronjob,计划每天更新一次表中的一些信息。该作业只是调用一个函数,该函数尝试更新表。发生的情况是,当信息更新时,列

request_at
会使用与
updated_at
相同的信息进行更新,但只有列
updated_at
status_id
应该更改

这是我的模型、迁移和 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);
    }
}

迁移

<?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');
    }
}

定时任务

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

我使用函数

DB::enableQueryLog()
来准确查看查询是什么,并得到以下结果:

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
  ]
]

正如我们所看到的,查询中没有提及

request_at
,但它还是发生了变化。

我尝试过使用

DB::table('stock_recharges')
代替模型
StockRecharge
,但结果是一样的

Laravel 9.52 MySQL 8.0.31

有人遇到过类似的事情吗?

mysql laravel eloquent
1个回答
0
投票

你可以尝试一下吗

->whereRaw('DATEDIFF(CURDATE(),requested_at)','=','4')

我认为它是冲突的,因为你在使用 whereRaw 搜索时定义了 requesed_at

© www.soinside.com 2019 - 2024. All rights reserved.