iro*_*eek 7 php laravel eloquent
我的项目中有 2 个 Eloquent 模型:App\StoredFile和App\StoredImageSize.
该StoredFile模型负责保存上传的文件信息。如果上传的文件是一个图像,那么 2 个缩略图将存储在存储中,它们的属性在 DB(StoredImageSize模型)中。
关系如下:
存储文件.php:
public function sizes()
{
return $this->hasMany('App\StoredImageSize');
}
Run Code Online (Sandbox Code Playgroud)
存储图像大小.php:
public function originalImage()
{
return $this->belongTo('App\StoredFile');
}
Run Code Online (Sandbox Code Playgroud)
StoredImageSize有一个观察者类 ( StoredImageSizeObserver),它已通过 ServiceProvider 注册并且运行良好。
问题是,当从数据库中删除后续行时,我想从存储(在我的情况下是硬盘)中删除实际文件。
StoredImageSizeObserver.php:
public function deleting(StoredImageSize $file)
{
Storage::delete($file->server_url);
}
Run Code Online (Sandbox Code Playgroud)
逻辑是这样的:
$file = StoredFile::find(1);
$file->sizes()->delete(); // it does delete all related rows from 'StoredImageSize' but not files from storage
$file->delete()
Run Code Online (Sandbox Code Playgroud)
实际上它从来没有像Laravel 文档所说的那样deleting从StoredImageSizeObserver类中调用方法:
通过 Eloquent 执行批量删除语句时,不会为已删除的模型触发删除和删除模型事件。这是因为在执行删除语句时实际上从未检索到模型。
那么,我应该如何应对这种情况?任何解决方案或建议将不胜感激。
在StoredFile模型中添加以下方法,您有两种选择:
首先 :
protected static function boot() {
parent::boot();
static::deleting(function(StoredFile $fileToDelete) {
foreach ($fileToDelete->sizes as $size)
{
$size->delete();
}
$fileToDelete->delete()
});
}
Run Code Online (Sandbox Code Playgroud)
第二 :
protected static function boot() {
parent::boot();
static::deleting(function(StoredFile $fileToDelete) {
$size_ids = $fileToDelete->sizes()->lists('id');
StoredImageSize::whereIn($size_ids)->delete();
$fileToDelete->delete()
});
}
Run Code Online (Sandbox Code Playgroud)
或者为StoredFile模型创建一个观察者,而不是为模型创建一个观察者StoredImageSize,因为正如您对文档所说的,删除事件不会为 StoredImageSize 元素级联!并在:)的deleting方法中执行与上述相同的操作StoredFileObserver