Skip to content

Instantly share code, notes, and snippets.

@haoflynet
Last active September 14, 2018 07:18
Show Gist options
  • Save haoflynet/d2d1f606873026e553877d3d17d2cb8e to your computer and use it in GitHub Desktop.
Save haoflynet/d2d1f606873026e553877d3d17d2cb8e to your computer and use it in GitHub Desktop.
替换Laravel deleted_at为NULL的默认行为,使deleted_at不能为NULL
<?php
/**
* 覆盖Laravel默认的SoftDeletingScope,用于替换软删除的默认行为,解决deleted_at必须为NULL的问题,为NULL的时候不能设置唯一键
* 即默认是whereNull更改为判断timestamp的0值,即'0000-00-00 00:00:00'(空字符串在某些数据库版本也是可以的,但是考虑到兼容性还是写全吧),以使deleted_at字段不为NULL
* 使用时只需要把之前Model中的`use SoftDeletes`替换为`use LaravelCustomSoftDeletes`即可
* 请自行替换本文件中的部分命名空间
*/
namespace Common;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\SoftDeletingScope;
/**
*
* Class CustomSoftDeletingScope
* @package Common
*/
class CustomSoftDeletingScope extends SoftDeletingScope
{
public function apply(Builder $builder, Model $model)
{
$builder->where($model->getQualifiedDeletedAtColumn(), '0000-00-00 00:00:00');
$this->extend($builder);
}
}
/**
* 复写Laravel自带的SoftDeletes中的部分方法
*
* Trait ComposedSoftDelete
* @package Common
*/
trait ComposedSoftDelete
{
/**
* Boot the soft deleting trait for a model.
*
* @return void
*/
public static function bootSoftDeletes()
{
static::addGlobalScope(new CustomSoftDeletingScope);
}
/**
* 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()} = '0000-00-00 00:00:00';
// 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 $this->{$this->getQualifiedDeletedAtColumn()} != '0000-00-00 00:00:00';
}
/**
* Get a new query builder that includes soft deletes.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withTrashed()
{
return (new static)->newQueryWithoutScope(new CustomSoftDeletingScope);
}
/**
* Get a new query builder that only includes soft deletes.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function onlyTrashed()
{
$instance = new static;
$column = $instance->getQualifiedDeletedAtColumn();
return $instance->newQueryWithoutScope(new CustomSoftDeletingScope)->where($column, '!=', '0000-00-00 00:00:00');
}
}
/**
* 只需要继承这个SoftDeletes即可实现替换
*
* Trait CustomSoftDeletes
* @package Common
*/
trait LaravelCustomSoftDeletes
{
use SoftDeletes, ComposedSoftDelete {
ComposedSoftDelete::bootSoftDeletes insteadof SoftDeletes;
ComposedSoftDelete::restore insteadof SoftDeletes;
ComposedSoftDelete::trashed insteadof SoftDeletes;
ComposedSoftDelete::withTrashed insteadof SoftDeletes;
ComposedSoftDelete::onlyTrashed insteadof SoftDeletes;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment