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

后端 未结 5 723
走了就别回头了
走了就别回头了 2020-12-05 14:06

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 th

相关标签:
5条回答
  • 2020-12-05 14:26

    For add record

    'name' => [
                    'required',
                    'string',
                    'min:3',
                    Rule::unique('products')->where(function ($query) {
                        return $query->where('store_id', Auth::user()->store_id);
                    })->whereNull('deleted_at'),                
                ],
    

    For edit that record

    'name' => [
                    'required',
                    'string',
                    'min:3',
                    Rule::unique('products')->where(function ($query) {
                        return $query->where('store_id', Auth::user()->store_id);
                    })->ignore($request->id, 'id')->whereNull('deleted_at'),                
                ],
    
    0 讨论(0)
  • 2020-12-05 14:27

    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
    
    }
    
    0 讨论(0)
  • 2020-12-05 14:29

    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

    0 讨论(0)
  • 2020-12-05 14:31

    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.

    0 讨论(0)
  • 2020-12-05 14:39

    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
    
    0 讨论(0)
提交回复
热议问题