Laravel父模型删除不会触发子模型删除事件



我正在使用 laravel 5.4。我有一个项目模型作为父模型,project_images模型作为子模型,这是子模型:

Schema::create('project_images', function (Blueprint $table) {
$table->increments('id');
$table->integer('project_id')->unsigned();
$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');
$table->string('file', 100);
$table->timestamps();
});

因此,正如预期的那样,每当我删除项目时,它的所有图像记录也将被删除。然后我在图像模型中创建了一个删除事件,如下所示:

protected $events = [
'deleted' => ProjectImageDeleting::class
];

如果我删除图像本身,那么此事件也会触发,但如果我删除项目,则不会。

我的问题

我应该如何使它工作,当我删除父事件时,子事件也会触发?我错过了什么吗?(我已经有事件和侦听器,当我删除图像时侦听器中的代码可以工作(

更新

我在迁移中删除了该行,并将项目模型更改为:

namespace AliMHZ;
use IlluminateDatabaseEloquentModel;
class Project extends Model
{
public function images()
{
return $this->hasMany(ProjectImage::class);
}
protected static function boot()
{
parent::boot();
static::deleting(function($project) {
$project->images()->delete();
});
}
}

这是我的图像模型:

namespace AliMHZ;
use IlluminateDatabaseEloquentModel;
use AliMHZEventsProjectImageDeleting;
class ProjectImage extends Model
{
protected $events = [
'deleting' => ProjectImageDeleting::class
];
public function project()
{
return $this->belongsTo(Project::class);
}
}

和事件:

namespace AliMHZEvents;
use IlluminateBroadcastingChannel;
use IlluminateQueueSerializesModels;
use IlluminateBroadcastingPrivateChannel;
use IlluminateBroadcastingPresenceChannel;
use IlluminateFoundationEventsDispatchable;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateContractsBroadcastingShouldBroadcast;
use AliMHZProjectImage;
class ProjectImageDeleting
{
use Dispatchable,
InteractsWithSockets,
SerializesModels;
public $image;
public function __construct(ProjectImage $image)
{
$this->image = $image;
}
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}

最后是听众:

namespace AliMHZListeners;
use AliMHZEventsProjectImageDeleting;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
class ProjectImageDeletingListener
{
public function __construct()
{
//
}
public function handle(ProjectImageDeleting $event)
{
Log::info("File to be deleted: " . $event->image->file);
}
}

在这些更改之后,当我删除项目时,它的所有图像也将被删除,但图像事件仍然没有触发,但如果只删除图像,那么该事件就会起作用。我正在 laravel 修补匠中对此进行测试,每次我更改任何模型时,我都会退出修补匠并再次享用午餐。

当您使用$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');时,删除是在数据库级别完成的,因此不会触发模型事件。

要触发所有相关的模型事件,您必须在模型中手动编写代码。

<?php
class Project extends Eloquent
{
public function images()
{
return $this->has_many('Image');
}
protected static function boot() {
parent::boot();
static::deleting(function($project) {
// This will trigger the ProjectImageDeleting event.
$project->images()->delete();
});
}
}
编辑

以回答编辑的部分问题

你能试试以下吗

namespace AliMHZ;
use IlluminateDatabaseEloquentModel;
class Project extends Model
{
public function images()
{
return $this->hasMany(ProjectImage::class);
}
protected static function boot()
{
parent::boot();
static::deleting(function($project) {
$project->images()->get()->each(function ($image) {
$image->delete();
});
});
}
}

如果您想阅读更多关于为什么会发生这种情况的信息,您可以在 GitHub 上阅读有关此问题的信息。

最新更新