Laravel 5 Validation unique pass variable placeholder

前端 未结 4 1847
时光说笑
时光说笑 2021-02-09 20:42

Is it possible to pass the unique validation method extra where clauses with a variable?

Heres an example:

In my model I have my validation rules.



        
相关标签:
4条回答
  • 2021-02-09 21:13

    The Laravel documentation on validation has a sub-section titled, “Adding Additional Where Clauses” in the unique rule section:

    You may also specify more conditions that will be added as "where" clauses to the query:

    'email' => 'unique:users,email_address,NULL,id,account_id,1'

    In the rule above, only rows with an account_id of 1 would be included in the unique check.

    Unfortunately you will have to concatenate a variable value if you want it passed as part of the conditions:

    'circle_id' => 'required|unique:donations,circle_id,NULL,id,cause_id,'.$causeId,
    

    Or you make it more readable by specifying validation rules as an array:

    'circle_id' => [
        'required',
        'unique:donations,circle_id,NULL,id,cause_id,'.$causeId,
    ],
    
    0 讨论(0)
  • 2021-02-09 21:14

    My suggestion in your case would be to wrap your rules in a function:

    public static function rules($causeId)
    {
        return array(
            'amount'    => 'required|numeric',
            'user_id'   => 'required|exists:users,id',
            'cause_id'  => 'required|exists:causes,id',
            'circle_id' => 'required|unique:donations,circle_id,NULL,id,cause_id,' . $causeId,
        );
    }
    

    And then call your function, passing in your value:

    $validator = Validator::make($input, Donation::rules($yourCauseId));
    

    I've had problems like this in the past, I've also wanted to use the values from other fields, in the rule for another field too. This tends to be the easiest way to get around it.

    0 讨论(0)
  • 2021-02-09 21:31

    Defined my own class, so the existing rules declared in the class can stay.

    protected $rules = array(
        "id" => 'unique_custom:data_groups,id,id=GroupId'
    );
    

    Then added a magic method for Laravel:

    public function getGroupIdAttribute() {
        return $this->id;
    }
    

    In the service provider boot method:

        \Illuminate\Support\Facades\Validator::extend('unique_custom', '\Module\UniqueDataValidator@validate');
    

    Then added the class to src folder for package:

                <?php
    
                namespace Module;
    
                use Illuminate\Database\Eloquent\Model;
                use Illuminate\Support\Facades\Cache;
                use Illuminate\Support\Facades\DB;
                use Illuminate\Support\Facades\Validator;
                use Illuminate\Validation\Concerns\ValidatesAttributes as ValidatesAttributes;
                use Illuminate\Validation\Rules\Unique;
    
                class UniqueDataValidator extends Validator
                {
    
                    use ValidatesAttributes;
    
                    protected $custom_messages = array(
                        'unique_custom' => 'The :attribute field must be unique',
                    );
    
    
                    /**
                     * Validate the uniqueness of an attribute value on a given database table.
                     *
                     * If a database column is not specified, the attribute will be used.
                     *
                     * @param  string  $attribute
                     * @param  mixed   $value
                     * @param  array   $parameters
                     * @return bool
                     */
                    public function validate($attribute, $value, $parameters, $validator)
                    {
    
                        $this->requireParameterCount(3, $parameters, 'unique_custom');
    
                        list($connection, $table) = $this->parseTable($parameters[0]);
                        $input    = $validator->getData(); // All attributes
    
                        $column = $this->getQueryColumn($parameters, $attribute);
    
                        $param1 = explode("=", $parameters[1]);
                        $value = $input[$param1[0]]; // Set value to attribute value
    
                        $exclude = [];
                        if (isset($parameters[2])) {
                            $exclude_values = explode("=", $parameters[2]);
                            $exclude_value = @$input[$exclude_values[0]];
    
                            if (!is_null($exclude_value)) {
                                $exclude_id = $exclude_values[0];
                                $exclude_value = $input[$exclude_values[0]];
    
                                if (!is_null($exclude_value)) {
                                    $exclude[$exclude_values[0]] = $exclude_value;
                                }
                            }
                        }
    
                        $query = DB::table("$table")->where($column, '=', $value);
    
                        foreach ($exclude as $key => $value) {
                            $query->where(function ($query) use ($key, $value) {
                                    $query->where($key, '!=', $value);
                            });
                        }
    
                        $validator->setCustomMessages($this->custom_messages);
    
                        return $query->count() == 0;
    
                    }
    
    
                }
    

    I did try and simply append my method to the existing unique method, but as they are in different class spaces, it was causing issues with Laravel's native methods:

    use ValidatesAttributes;
    $this->validateUnique($attribute, $value, $parameters);
    
    0 讨论(0)
  • 2021-02-09 21:35

    in Laravel 5, your "public function rules()" is supposed to be in your FormRequest object:

    <?php 
    namespace your-namespace;
    
    use Illuminate\Foundation\Http\FormRequest;
    class MyFormRequest extends FormRequest {
    
        public function rules() {
           return [
              'field'    => 'required|unique:table,column,user_id,' . $this->input('field-or-whatever-you-need-from-request'),
           ];
        }
    }
    ?>
    
    0 讨论(0)
提交回复
热议问题