【问题标题】:How to ignore uniqueness for multiple fields如何忽略多个字段的唯一性
【发布时间】:2017-03-11 20:15:44
【问题描述】:

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

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

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

谢谢。

【问题讨论】:

  • 添加额外的 Where 子句。

标签: php mysql laravel-5.3


【解决方案1】:

自定义规则

最好的解决方案是为此创建一个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),因此它知道用户选择了哪个城市。有了这些信息,您现在可以检查是否已经有与输入城市名称相同的学校。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2019-11-14
      • 2021-02-10
      • 2018-04-28
      • 1970-01-01
      • 2011-05-27
      • 2021-03-25
      • 1970-01-01
      • 2010-12-10
      相关资源
      最近更新 更多