是否可以将带有变量的子句的唯一验证方法传递给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'
答案 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)
-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);