我的db中有以下值:
id - name - created_at - updated_at - deleted_at
------------------------------------------------
1 - John - 2018-11-11 - 2018-11-11 - (NULL)
2 - John - 2018-11-11 - 2018-11-11 - 2018-11-11如果我用Datatable (Yajra)搜索" John“,我只看到带有id=1的John,因为我使用的是软删除。我的模型是:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class MyModel extends Model
{
use SoftDeletes;
protected $fillable = ['name'];
protected $dates = ['deleted_at'];
}当我删除(销毁)一个注册表时,它将一个日期放在deleted_at,这是正确的。但是,当我想编辑(更新) John时,Validator给出了这个值已经在使用的错误。我的更新方法是:
public function update(Request $request, $id)
{
$rules = array(
'name' => 'unique:my_table'
);
$validator = Validator::make($request->all(), $rules);
if ($validator->passes()) {
MyModel::find($id)->update($request->input());
return redirect()->route('myroute')->withFlashSuccess('Ok!');
} else {
return redirect()->back()->withInput()->withErrors($validator);
}
}我做错什么了?
发布于 2018-05-05 01:52:39
这个问题与SoftDeletes无关,它是一个验证问题。unique验证规则非常特殊,因为在更新的情况下,它需要知道在执行验证时可能忽略哪些条目。在后台,规则执行如下所示的SQL查询
IF EXISTS (
SELECT id
FROM my_table
WHERE name = 'some value'
)
SELECT 1
ELSE
SELECT 0(它可能不是确切的查询,但类似)。
如您所见,如果执行更新或不执行更新,则查询不会考虑。因为您的实体已经存在,它将返回1,因此无法验证,因为它认为验证下的值并不是唯一的。
但实际上有一种方法可以使验证工作用于更新。您只需将现有实体(正在验证的)的id作为第三个参数添加到验证规则中。所以你的规则应该是这样的:
$rules = [
'name' => 'unique:my_table,name,'.$id
];请注意,unique验证规则还有第二个参数--要搜索的数据库表的列。
编辑:
如果唯一约束仅与未删除的条目相关,这意味着如果将相同值的其他出现标记为已删除,则可以重用唯一值,则可能有必要向unique验证规则中添加一个附加的unique子句。为此,需要将第四个参数设置为identifier列名,然后我们可以将附加的where子句添加为两个参数的对。
$rules = [
'name' => 'unique:my_table,name,'.$id.',id,deleted_at,NULL'
];这将将where('deleted_at', 'NULL') (或whereNull('deleted_at'))添加到查询中。
发布于 2018-05-05 01:58:11
这个人写了一篇似乎能解决你问题的博文:
https://wisdmlabs.com/blog/laravel-soft-delete-unique-validations/
我不能100%肯定您想要这样做,不过以后您可能希望使用restore()方法将软删除的数据返回。那样的话,你就会发生碰撞。
https://stackoverflow.com/questions/50184868
复制相似问题