修改model軟刪除欄位型別
公司專案新版本開發,在討論表結構修改的時候需要問題。laravel 預設的軟刪除欄位deleted_at 預設值為null ,就讓修改成預設值不為null。從網上搜了一些解決方案之後,自己整理了下。
直接上程式碼
SoftDeletes檔案
<?php
namespace App\Utils;
/**
* @method static static|\Illuminate\Database\Eloquent\Builder| \Illuminate\Database\Query\Builder withTrashed(bool $withTrashed = true)
* @method static static|\Illuminate\Database\Eloquent\Builder| \Illuminate\Database\Query\Builder onlyTrashed()
* @method static static|\Illuminate\Database\Eloquent\Builder| \Illuminate\Database\Query\Builder withoutTrashed()
*/
trait SoftDeletes
{
/**
* Indicates if the model is currently force deleting.
*
* @var bool
*/
protected $forceDeleting = false;
/**
* Boot the soft deleting trait for a model.
*
* @return void
*/
public static function bootSoftDeletes()
{
static::addGlobalScope(new SoftDeletingScope);
}
/**
* Initialize the soft deleting trait for an instance.
*
* @return void
*/
public function initializeSoftDeletes()
{
if (! isset($this->casts[$this->getDeletedAtColumn()])) {
$this->casts[$this->getDeletedAtColumn()] = 'datetime';
}
}
/**
* 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()
{
return $this->runSoftDelete();
}
/**
* Perform the actual delete query on this model instance.
*
* @return void
*/
protected function runSoftDelete()
{
$query = $this->newModelQuery()->where($this->getKeyName(), $this->getKey());
$columns = [$this->getDeletedAtColumn() => time()];
if ($query->update($columns)) {
$this->syncOriginal();
}
}
/**
* 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()} = 0;
// 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()});
return ! $this->{$this->getDeletedAtColumn()} == 0;
}
/**
* Register a "softDeleted" model event callback with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function softDeleted($callback)
{
static::registerModelEvent('trashed', $callback);
}
/**
* Register a "restoring" model event callback with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function restoring($callback)
{
static::registerModelEvent('restoring', $callback);
}
/**
* Register a "restored" model event callback with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function restored($callback)
{
static::registerModelEvent('restored', $callback);
}
/**
* Register a "forceDeleted" model event callback with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function forceDeleted($callback)
{
static::registerModelEvent('forceDeleted', $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 'deleted';
}
/**
* Get the fully qualified "deleted at" column.
* 獲取刪除欄位名稱,qualifyColumn會只能補充表的名稱
* @return string
*/
public function getQualifiedDeletedAtColumn()
{
return $this->qualifyColumn($this->getDeletedAtColumn());
}
}
SoftDeletingScope檔案
<?php
namespace App\Utils;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class SoftDeletingScope implements Scope
{
/**
* All of the extensions to be added to the builder.
*
* @var string[]
*/
protected $extensions = ['Restore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed'];
/**
* 把約束加到 Eloquent 查詢構造中.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->where($model->getQualifiedDeletedAtColumn(), 0);
// $builder->where($model->getTable().'.deleted', '=', 0);
}
/**
* Extend the query builder with the needed functions.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
public function extend(Builder $builder)
{
foreach ($this->extensions as $extension) {
$this->{"add{$extension}"}($builder);
}
$builder->onDelete(function (Builder $builder) {
$column = $this->getDeletedAtColumn($builder);
return $builder->update([
$column => $builder->getModel()->freshTimestampString(),
]);
});
}
/**
* Get the "deleted at" column for the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return string
*/
protected function getDeletedAtColumn(Builder $builder)
{
if (count((array) $builder->getQuery()->joins) > 0) {
return $builder->getModel()->getQualifiedDeletedAtColumn();
}
return $builder->getModel()->getDeletedAtColumn();
}
/**
* Add the restore extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addRestore(Builder $builder)
{
$builder->macro('restore', function (Builder $builder) {
$builder->withTrashed();
return $builder->update([$builder->getModel()->getDeletedAtColumn() => null]);
});
}
/**
* Add the with-trashed extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addWithTrashed(Builder $builder)
{
$builder->macro('withTrashed', function (Builder $builder, $withTrashed = true) {
if (! $withTrashed) {
return $builder->withoutTrashed();
}
return $builder->withoutGlobalScope($this);
});
}
/**
* Add the without-trashed extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addWithoutTrashed(Builder $builder)
{
$builder->macro('withoutTrashed', function (Builder $builder) {
$model = $builder->getModel();
$builder->withoutGlobalScope($this)->whereNull(
$model->getQualifiedDeletedAtColumn()
);
return $builder;
});
}
/**
* Add the only-trashed extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addOnlyTrashed(Builder $builder)
{
$builder->macro('onlyTrashed', function (Builder $builder) {
$model = $builder->getModel();
$builder->withoutGlobalScope($this)->whereNotNull(
$model->getQualifiedDeletedAtColumn()
);
return $builder;
});
}
}
應用方法
使用方法參考文件:https://learnku.com/docs/laravel/8.5/eloquent/10409#ad4448
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Test extends Model
{
use SoftDeletes;
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結