是否可以传递带有变量的唯一验证方法extrawhere子句?
下面是一个示例:
在我的模型中,我有我的验证规则。
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?正如您在规则数组中看到的那样,我已经尝试了 PDO 样式:p laceholder,但查询执行为: select count(*) as aggregate from donations where circle_id = '500' and cause_id = ':cause_id'
在您的情况下,我的建议是将您的规则包装在一个函数中:
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));
我过去遇到过这样的问题,我也想在另一个字段的规则中使用其他字段中的值。这往往是解决它的最简单方法。
关于验证的Laravel文档在唯一规则部分中有一个标题为"添加其他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,
],
在 Laravel 5 中,你的"public function rules()"应该在你的 FormRequest 对象中:
<?php
namespace your-namespace;
use IlluminateFoundationHttpFormRequest;
class MyFormRequest extends FormRequest {
public function rules() {
return [
'field' => 'required|unique:table,column,user_id,' . $this->input('field-or-whatever-you-need-from-request'),
];
}
}
?>
定义了我自己的类,因此类中声明的现有规则可以保留。
protected $rules = array(
"id" => 'unique_custom:data_groups,id,id=GroupId'
);
然后给拉拉维尔加了一个神奇的方法:
public function getGroupIdAttribute() {
return $this->id;
}
在服务提供商引导方法中:
IlluminateSupportFacadesValidator::extend('unique_custom', 'ModuleUniqueDataValidator@validate');
然后将类添加到包的 src 文件夹中:
<?php
namespace Module;
use IlluminateDatabaseEloquentModel;
use IlluminateSupportFacadesCache;
use IlluminateSupportFacadesDB;
use IlluminateSupportFacadesValidator;
use IlluminateValidationConcernsValidatesAttributes as ValidatesAttributes;
use IlluminateValidationRulesUnique;
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);