如何忽略多个字段的唯一性

How to ignore uniqueness for multiple fields

我有两个模型:城市和学校。正如您已经了解的那样,城市可以有很多学校,考虑到这一点,我将我的模型定义如下:

class School extends Model
{
   public $fillable = ['city_id' ,'name'];

     public function city()
    {
        return $this->belongsTo('App\City','city_id','id');
    }

}

class City extends Model
{
    public $fillable = ['name'];

    Public function schools()
    {
        return $this->hasMany('App\School', 'id','city_id');
    }
}

但是我在尝试验证学校模型的更新时遇到了问题。我必须验证学校名称对于所选城市是否是唯一的。我定义了这样的规则:

$rules = array(
  'name' => ['required', Rule::unique('schools')->ignore($id)],
);
$validator=Validator::make(Input::all(),$rules);

但不允许在所选城市以外的其他城市保存现有名称的学校。如果城市不同,我应该如何更改规则以确保学校名称可以相同。

谢谢。

在数据库级别,听起来您想要的是跨名称和 city_id 的复合唯一性约束。 Eloquent 似乎支持在模型定义中传递列名数组。不过,这似乎需要自定义验证。参见 Laravel 4: making a combination of values/columns unique and the custom validator at https://github.com/felixkiss/uniquewith-validator

自定义规则

最好的解决方案是为此创建一个 custom rule,它接受具有相应城市 name/id 的字段作为参数。

类似

//Calling the custom rule like this
['name' => 'required|validateSchool:yourFieldNameOfCityHere'];

像这样在您的服务提供商中声明自定义验证函数

Validator::extend('validateSchool', function ($attribute, $value, $parameters, $validator) {
   $cityName = ($validator->data, $parameters[0]);

   //Now check if the $value is already set for the specific city by using normal database queries and comparison
  return count(City::whereName($cityName)->schools()->whereName($value)->get()) == 0
});

它是做什么的

自定义验证规则接收您用函数提供的字段数据(在上面的代码中是yourFieldNameOfCityHere),因此它知道用户选择了哪个城市。有了这些信息,您现在可以检查是否已经有与所输入城市名称相同的学校。