Laravel,无法更新软删除的值

时间:2018-05-05 01:29:48

标签: laravel validation soft-delete

我在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”,我只会看到John id=1,因为我正在使用softdeletes。我的模型是这样的:

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);
    }
}

我做错了什么?

2 个答案:

答案 0 :(得分:2)

此人撰写了一篇博客文章,看起来可以解决您的问题:

https://wisdmlabs.com/blog/laravel-soft-delete-unique-validations/

我不是100%确定你想要这样做,因为你可能以后希望使用restore()方法来恢复软删除的数据。在这一点上,你会发生碰撞。

答案 1 :(得分:1)

问题与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验证规则还有第二个参数 - 您要搜索的数据库表的列。

修改

如果唯一约束仅与未删除的条目相关,则意味着如果将相同值的其他出现标记为已删除,则可以重用唯一值,则可能需要添加where()验证规则的附加unique子句。为此,需要将第四个参数设置为identifier列名称,然后我们可以将其他where子句添加为两个参数对。

$rules = [
    'name' => 'unique:my_table,name,'.$id.',id,deleted_at,NULL'
];

这会将where('deleted_at', 'NULL')(或whereNull('deleted_at'))添加到查询中。