Laravel 5 Validation唯一传递变量占位符

时间:2015-04-17 10:31:24

标签: php validation laravel laravel-5

是否可以将带有变量的子句的唯一验证方法传递给where?

以下是一个例子:

在我的模型中,我有验证规则。

public static $rules = 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,:cause_id',
);

然后在我的控制器中运行:

$input = array(
    'amount'    => Input::get('amount'),
    'user_id'   => $this->currentUser->id,
    'cause_id'  => $cause->id,
    'circle_id' => Input::get('circle_id')
);

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

如何在不连接验证规则的情况下获取cause_id?正如您在rules数组中看到的那样,我尝试了PDO样式:占位符,但查询执行如下: select count(*) as aggregate from donations where circle_id = '500' and cause_id = ':cause_id'

4 个答案:

答案 0 :(得分:3)

我的建议是将你的规则包装在一个函数中:

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

然后调用你的函数,传递你的值:

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

我过去曾遇到过这样的问题,我也想在其他字段的规则中使用其他字段的值。这往往是解决问题的最简单方法。

答案 1 :(得分:1)

Laravel documentation on validation在唯一规则部分中有一个标题为“添加其他Where子句”的小节:

  

您还可以指定更多条件,将其添加为查询的“where”子句:

     

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

     

在上述规则中,只有account_id 1的行才会包含在唯一身份检查中。

不幸的是,如果您希望将变量值作为条件的一部分传递,则必须连接变量值:

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

或者通过将验证规则指定为数组来使其更具可读性:

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

答案 2 :(得分:1)

在Laravel 5中,你的“公共函数规则()”应该在你的FormRequest对象中:

-l

答案 3 :(得分:0)

定义了我自己的类,因此在类中声明的现有规则可以保留。

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

然后为Laravel添加了一个神奇的方法:

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

在服务提供商启动方法中:

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

然后将类添加到包的src文件夹中:

            <?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;

                }


            }

我确实尝试将我的方法简单地附加到现有的唯一方法,但由于它们位于不同的类空间中,因此导致了Laravel的本机方法出现问题:

use ValidatesAttributes;
$this->validateUnique($attribute, $value, $parameters);