关于软删除问题
需求:软删除时,记录一下删除的操作用户是谁,
所以设计数据表的时候,增加字段 deleted_by , deleted_at
发现执行 Book::destroy(1); 只修改了deleted_at。这时候我想增加一个模型事件
public static function boot()
{
parent::boot();
static::deleting(function ($model) {
$model->deleted_by = Auth::id();
});
}
发现不生效。
这时候,我手动建了一个Traits。其他代码一样,只是runSoftDelete加一行代码.. 然后我的模型use App\Traits\SoftDeletes;(我自定义的)
<?php
namespace App\Traits;
use App\Repositories\AuthRepository;
use Illuminate\Database\Eloquent\SoftDeletingScope;
/**
* 自定义软删除,增加一个删除用户ID.
*/
trait SoftDeletes
{
/**
* Indicates if the model is currently force deleting.
*
* @var bool
*/
protected $forceDeleting = false;
/**
* Boot the soft deleting trait for a model.
*/
public static function bootSoftDeletes()
{
static::addGlobalScope(new SoftDeletingScope());
}
/**
* Initialize the soft deleting trait for an instance.
*/
public function initializeSoftDeletes()
{
$this->dates[] = $this->getDeletedAtColumn();
}
/**
* Force a hard delete on a soft deleted model.
*
* @return bool|null
*/
public function forceDelete()
{
$this->forceDeleting = true;
return tap($this->delete(), function ($deleted) {
$this->forceDeleting = false;
if ($deleted) {
$this->fireModelEvent('forceDeleted', false);
}
});
}
/**
* Perform the actual delete query on this model instance.
*
* @return mixed
*/
protected function performDeleteOnModel()
{
if ($this->forceDeleting) {
$this->exists = false;
return $this->newModelQuery()->where($this->getKeyName(), $this->getKey())->forceDelete();
}
return $this->runSoftDelete();
}
/**
* Perform the actual delete query on this model instance.
*/
protected function runSoftDelete()
{
$query = $this->newModelQuery()->where($this->getKeyName(), $this->getKey());
$time = $this->freshTimestamp();
$columns = [$this->getDeletedAtColumn() => $this->fromDateTime($time)];
$this->{$this->getDeletedAtColumn()} = $time;
if ($this->timestamps && !is_null($this->getUpdatedAtColumn())) {
$this->{$this->getUpdatedAtColumn()} = $time;
$columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);
}
/**
* 删除时候,增加用户ID.
*/
$columns['deleted_by'] = Auth::id();
$query->update($columns);
}
/**
* Restore a soft-deleted model instance.
*
* @return bool|null
*/
public function restore()
{
// If the restoring event does not return false, we will proceed with this
// restore operation. Otherwise, we bail out so the developer will stop
// the restore totally. We will clear the deleted timestamp and save.
if ($this->fireModelEvent('restoring') === false) {
return false;
}
$this->{$this->getDeletedAtColumn()} = null;
// Once we have saved the model, we will fire the "restored" event so this
// developer will do anything they need to after a restore operation is
// totally finished. Then we will return the result of the save call.
$this->exists = true;
$result = $this->save();
$this->fireModelEvent('restored', false);
return $result;
}
/**
* Determine if the model instance has been soft-deleted.
*
* @return bool
*/
public function trashed()
{
return !is_null($this->{$this->getDeletedAtColumn()});
}
/**
* Register a restoring model event with the dispatcher.
*
* @param \Closure|string $callback
*/
public static function restoring($callback)
{
static::registerModelEvent('restoring', $callback);
}
/**
* Register a restored model event with the dispatcher.
*
* @param \Closure|string $callback
*/
public static function restored($callback)
{
static::registerModelEvent('restored', $callback);
}
/**
* Determine if the model is currently force deleting.
*
* @return bool
*/
public function isForceDeleting()
{
return $this->forceDeleting;
}
/**
* Get the name of the "deleted at" column.
*
* @return string
*/
public function getDeletedAtColumn()
{
return defined('static::DELETED_AT') ? static::DELETED_AT : 'deleted_at';
}
/**
* Get the fully qualified "deleted at" column.
*
* @return string
*/
public function getQualifiedDeletedAtColumn()
{
return $this->qualifyColumn($this->getDeletedAtColumn());
}
}
有没有好一点的方法?
关于 Laravel 的的软删除确实有些瑕疵,有时候也不是很方便。
像这个也只能自定义
SoftDeletes
来处理了,但我想提示两点Illuminate\Database\Eloquent\SoftDeletes
这个trait
SoftDeletes
后部分关联模型的软删除字段处理失效的问题代码如下
是否可以在
updating
事件中,尝试使用isDirty
方法,来判断当前是否是软删除操作?deleting替换成deleted试试?
为啥不用Observer 呢?
示例地址
https://github.com/summerblue/larabbs/sear...
改下
SoftDeletes
里的runSoftDelete
方法即可:请问下作者,我使用
Laravel 6
在runSoftDelete
增加参数没有作用