我正在使用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 Illuminate\Database\Eloquent\Model;
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 Illuminate\Database\Eloquent\Model;
use AliMHZ\Events\ProjectImageDeleting;
class ProjectImage extends Model
{
protected $events = [
'deleting' => ProjectImageDeleting::class
];
public function project()
{
return $this->belongsTo(Project::class);
}
}
和事件:
namespace AliMHZ\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use AliMHZ\ProjectImage;
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 AliMHZ\Listeners;
use AliMHZ\Events\ProjectImageDeleting;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProjectImageDeletingListener
{
public function __construct()
{
//
}
public function handle(ProjectImageDeleting $event)
{
\Log::info("File to be deleted: " . $event->image->file);
}
}
在这些更改之后,当我删除项目时,其所有图像也将被删除,但图像事件仍然不会启动,但如果仅删除图像,则事件有效。我正在用laravel修补器进行测试,每当我改变任何模型时,我都会退出修补匠并再次吃午饭。
答案 0 :(得分:1)
当您使用$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 Illuminate\Database\Eloquent\Model;
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();
});
});
}
}
如果您想详细了解原因,可以在this issue on GitHub上阅读。