我最终扩展了 Validator 类来定义自定义验证规则。我主要在我的应用程序中检查
first_name
字段,因为我不想在生成全名时做额外的工作。除了将其设置为复合值(在考虑问题后是不必要的),我简单地将其设置为检查指定字段的所有值的
AND
。您可以指定任意数量的字段,如果其中一个字段不存在于验证器数据中,则会引发异常。我甚至不确定是否仅使用现有的
unique
规则就可以完成此操作,但无论如何这都是一个很好的练习。
'first_name' => 'unique_multiple_fields:members,first_name,last_name'
我的验证器子类代码:
use Illuminate\Validation\Validator as IlluminateValidator;
class CustomValidatorRules extends IlluminateValidator
{
protected function validateUniqueMultipleFields( $attribute, $value, $parameters )
{
if (is_null($parameters) || empty($parameters)) {
throw new \InvalidArgumentException('Expected $parameters to be a non-empty array.');
}
if (count($parameters) < 3) {
throw new \InvalidArgumentException('The $parameters option should have at least 3 items: table, field1, field2, [...], fieldN.');
}
$table = array_shift($parameters);
$modelName = preg_replace("/^(.*)([s])$/", "$1", ucfirst($table));
$select = $modelName::select($parameters);
foreach ($parameters as $fieldName) {
$curFieldVal = ($fieldName === $attribute) ? $value : $this->data[$fieldName];
if (is_null($curFieldVal)) {
throw new \Exception("Expected `{$fieldName}` data to be set in the validator.");
}
$select->where($fieldName, '=', $curFieldVal);
}
$numFound = $select->count();
return ($numFound === 0);
}
}
如果你好奇的话,我确实使用了我最初想到的复合方法使它工作了。其代码如下。结果发现“分隔符”是完全没有意义的,所以我最终重构它,使用上面指定的多字段方法。
use Illuminate\Validation\Validator as IlluminateValidator;
class CustomValidatorRules extends IlluminateValidator
{
protected function validateUniqueComposite( $attribute, $value, $parameters )
{
if (is_null($parameters) || empty($parameters)) {
throw new \InvalidArgumentException('Expected $parameters to be a non-empty array.');
}
if (count($parameters) < 3) {
throw new \InvalidArgumentException('The $parameters option should have at least 3 items: table, field1, field2, [...], fieldN.');
}
$table = array_shift($parameters);
$separator = '';
$lastParam = array_pop($parameters);
if (! isset($this->data[$lastParam])) {
$separator = $lastParam;
}
$fields = array();
foreach ($parameters as $fieldName) {
array_push($fields, $table . "." . $fieldName);
}
$fields = implode(', ', $fields);
$dataFieldValues = array();
foreach ($parameters as $fieldName) {
$curFieldVal = ($fieldName === $attribute) ? $value : $this->data[$fieldName];
if (is_null($curFieldVal)) {
throw new \Exception("Expected `{$fieldName}` data.");
}
array_push($dataFieldValues, $curFieldVal);
}
$compositeValue = implode($separator, $dataFieldValues);
$modelName = preg_replace("/^(.*)([s])$/", "$1", ucfirst($table));
$raw = \DB::raw("concat_ws('" . $separator . "', " . $fields . ")");
$model = new $modelName;
$select = $modelName::where($raw, '=', $compositeValue);
$numFound = $select->count();
return ($numFound === 0);
}
}
app/validators.php
中,并使用require app_path().'/validators.php';
在app/start/global.php
中包含它。 - Bogdan未定义列:7 ERROR:列“composite_value”不存在
。 - Derek