Check if name is unique among non-deleted items with laravel validation

╄→尐↘猪︶ㄣ 提交于 2019-12-03 15:46:45

问题


I have a simple form which posts to a controller which checks if a name for an item is already taken for a particular project. If it is, then it returns an error. This is the code I'm using for that:

'name'    => 'required|min:1|unique:versions,name,NULL,id,project_id,'.$project->id,

The problem I've run into is that instead of a hard delete, I'm using a soft delete to remove them from the database, meaning that, for example, 'Test' can only be used as the name once, even after it's been deleted.

How can I make it check that it is unique for that project among the items that are not soft deleted?


回答1:


You may try this:

'name' => 'required|min:1|unique:versions,name,NULL,id,deleted_at,NULL'

This will make sure that the name in the versions table will be unique, if a record is soft deleted and has same name name then it won't be counted, means, name will be accepted even if there is a soft deleted record with the same name exists.

To ignore a model when updating, you should pass the id after name in the place of first NULL.

Update: Also you may use something like this to add your own custom rule:

// You can declare it inside your controller method before you run validation
Validator::extend('unique_project', function($attribute, $value, $parameters)
{
   // $attribute will contain field name, i.e. name
   // $value will contain the value in the $attribute/name
   // $parameters will be an array of arguments passed
   // i.e. [0] => arg1, [1] => arg2, [2] => arg3 and so on

   return true for valid and false for invalid

});

You may use it like this:

'name' => 'required|min:1|unique_project:arg1,arg2,arg3' // add more args if needed



回答2:


I know this question is old, but I stumbled across this when looking for a solution to a similar problem. You don't need custom validation code.

I have a database of ledger codes in which the 'name' and 'short_name' must be unique for each user (user_id). I have soft deletes enabled, so they should only be unique among non-deleted rows for a given user.

This is my function which returns the validation strings:

protected function validation_data($user_id, $update_id = "NULL") {
        return [
        'name' => "required|max:255|unique:ledger_codes,name,$update_id,id,deleted_at,NULL,user_id,$user_id",
        'short_name' => "max:255|min:3|unique:ledger_codes,short_name,$update_id,id,deleted_at,NULL,user_id,$user_id",
        'description' => 'max:255',
        ];
    }

For any one wondering about the argument string syntax for the unique validator, it is as follows:

  • arg 0: The table name in the database
  • arg 1: the field name in which the value is unique
  • arg 2: a single id which is to be ignored (set to uppercase NULL if you are not using it.)
  • arg 3: the field in which the single id resides. It defaults to 'id' so if you are not using it, and you have more arguments, use the string 'id'.
  • arg 4/5: a field name/value pair for a where clause (where('deleted_at',null) in my example.)
  • arg 6/7: another field name/value pair (where('user_id', $user_id) in my example).
  • arg 8/9: another field name value pair
  • arg 10/11: another.......
    ... and so on.

The value fields in field name/value pairs can be either a value to match, NULL, or NOT_NULL.




回答3:


If someone is looking for solution using Rule class.

use Illuminate\Validation\Rule;

class UpdateArticleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $data = $this->request->all();

        return [
            'slug' => [
                'required',                
                Rule::unique('articles')->ignore($data['id'])->whereNull('deleted_at')
            ]
        ];
    }
}

Basically, we just ignoring rows which deleted_at fields are not null.

Here are the methods which you can use along with ignore function: https://laravel.com/api/5.7/Illuminate/Validation/Rules/DatabaseRule.html




回答4:


On Create Method:

public function store(Request $request)
{

    $request->validate([

        'name'=>'required|unique:form_types,name,NULL,id,deleted_at,NULL',

    ]);

    // Write your code here

}

On Update Method:

public function update(Request $request, $id)
{

    $request->validate([

        'name'=>'required|unique:form_types,name,'.$id.',id,deleted_at,NULL',

    ]);

    // Write Code here

}


来源:https://stackoverflow.com/questions/23374995/check-if-name-is-unique-among-non-deleted-items-with-laravel-validation

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