php Laravel -关联与设置观察者事件ID

nhaq1z21  于 2022-12-28  发布在  PHP
关注(0)|答案(1)|浏览(126)

我有一个Sample模型,它有一个状态(字符串)和一个当前任务(Task模型的外键)。

field              type
---------------------------
id                 int
status             string -> I use an Enum to store possible values
current_task_id    int -> foreign key to the Task model

在我的模型中,我将关系定义如下:

public function currentTask()
{
    return $this->belongsTo(Task::class, 'current_task_id', 'id');
}

现在,我已经创建了一个Observer,它具有以下函数:

public function updated(Sample $sample)
{
    // check if the current task is null and if not change the status to in progress
    Log::info('Sample status changed to in progress', ['sample' => $sample->toArray()]);
    if ($sample->currentTask()->exists()) {
        $sample->status = 'in progress';
        $sample->save();
    }
}

我希望在更新示例时触发此操作,检查是否有关联的Task,如果有,则将状态更改为In Progress。
我遇到了两个问题:
1.当手动更新current_task_id字段并运行保存()时,我遇到了由观察者代码引起的内存泄漏。
1.当运行“associate”方法来分配 currentTask 时,观察器不会触发。
请看下面我在Tinkerwell中运行的代码

$sample = Sample::factory()->create();
echo $sample->currentTask(); // null
echo $sample->status;        // not started
$sample->current_task_id = 2;
$sample->save();             // memory leak, additionally, if I check $sample->currentTask it gives me null...

或与同事:

$sample = Sample::factory()->create();
echo $sample->currentTask(); // null
echo $sample->status;        // not started
$sample->currentTask()->associate(2); // does not trigger observer
echo $sample->currentTask(); // Task object
echo $sample->status;        // not started

我怎样才能触发associate上的观察器?或者,为什么保存()会导致内存泄漏?

ymdaylpp

ymdaylpp1#

以下是我的建议:
继续使用观察者,但使用保存(或更新)方法:

public function saving(Sample $sample)
{
    // check if the current task changed
    Log::info('Sample status changed to in progress', ['sample' => $sample->toArray()]);
    if ($sample->isDirty('current_task_id') && CurentTask::where('id', $sample->current_task_id)->exists()) {
        $sample->status = 'in progress';
    }
}

如果在savingupdating事件中不使用isDirty检查,则最终将出现保存、触发updated并再次保存的无限循环

相关问题