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

时间:2017-03-11 20:15:44

标签: php mysql laravel-5.3

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

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

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

谢谢。

2 个答案:

答案 0 :(得分:0)

在数据库级别,听起来你想要的是名称和city_id之间的复合唯一性约束。 Eloquent似乎支持在模型定义中传递一组列名。但是,这似乎需要自定义验证。请参阅Laravel 4: making a combination of values/columns uniquehttps://github.com/felixkiss/uniquewith-validator

上的自定义验证程序

答案 1 :(得分:0)

自定义规则

最好的解决方案是为此创建custom rule,接受具有相应城市名称/ 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),因此它知道用户选择的城市。有了这些信息,您现在可以检查是否已有一所学校,其中包含输入城市的名称。