Laravel, Can't update a soft-deleted value

你。 提交于 2019-12-13 01:46:39

问题


I have this values in my 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

If I search for "John" with my Datatable (Yajra) I only see the John with id=1 because I'm using softdeletes. My model is this:

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'];
}

When I delete (destroy) a registry it puts a date at deleted_at which is correct. But when I want to edit (update) John the Validator is giving me the error that that value is already in use. My update method is this:

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

What I'm doing wrong?


回答1:


The problem has nothing to do with the SoftDeletes, it is a validation issue. The unique validation rule is very special, because in case of an update it needs to know which entry it may ignore when performing the validation. In the background, the rule is performing an SQL query like

IF EXISTS (
    SELECT id
    FROM   my_table
    WHERE  name = 'some value'
) 
    SELECT  1
ELSE 
    SELECT  0

(it may not be the exact query, but similar).

As you can see, the query does not take into account if you perform an update or not. Because your entity already exists, it will return 1 and therefore fail the validation because it thinks that the value under validation is not unique.

But there is actually a way to make the validation work for updates. You simply have to add the id of the existing entity (which is being validated) as third parameter to the validation rule. So your rules should look something like this:

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

Please be aware that there is also a second parameter for the unique validation rule - the column of the database table you want to search in.


Edit:

In case the unique constraint does only relate to not deleted entries, meaning that a unique value may be reused if other occurences of the same value are flagged as deleted, then it may be necessary to add an additional where() clause to the unique validation rule. For this, the fourth parameter needs to be set to the identifier column name and then we can add the additional where clauses as pairs of two parameters.

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

This will add where('deleted_at', 'NULL') (or whereNull('deleted_at')) to the query.




回答2:


This person has written a blog post that looks like it would solve your problem:

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

I'm not 100% sure you want to do this though as you may later wish to use the restore() method to bring the soft-deleted data back. At which point, you'll have a collision.



来源:https://stackoverflow.com/questions/50184868/laravel-cant-update-a-soft-deleted-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!