【问题标题】:How to create custom validation rule for 4 combinedly unique columns如何为 4 个组合唯一的列创建自定义验证规则
【发布时间】:2018-04-30 06:51:54
【问题描述】:

由于 Laravel 默认的 unique:tablename 验证规则只允许两列;在多于两列是唯一的情况下,它直接将QueryExceptionSQLSTATE errorcode 23000 一起抛出。作为临时解决方法,我正在捕获异常并发出如下警告:

try{
    //My query that might throw an exception for a duplicate entry
} catch (\Exception $e){
    return $e->getCode() == 23000 ?
           redirect()->back()->with('warning','Duplicate entry') :
           redirect()->back()->with('error','Unknown Error Occurred');
}

问题是,对于错误代码不是 23000 的所有其他情况,我只会看到错误消息 Unknown Error Occurred 而不是 Whoops。显然,调试将是一场噩梦。

所以我寻找替代品。我必须选择以下两个选项之一:a) 使用 third party package 或者,b) 创建 custom validation rule

我选择了选项 b。但我正在为如何自己建造一个而苦苦挣扎。当我查看一个示例时(对于一次性内联规则):

$validator = Validator::make($request->all(), [
    'title' => [
       'required',
       'max:255',
        function($attribute, $value, $fail) {
            if ($value === 'foo') {
                return $fail($attribute.' is invalid.');
            }
        },
    ],
]);

...我意识到该规则只能应用于单个属性和值。但我有 4 个属性和值来检查它们是否确实是唯一条目。我该怎么做?

【问题讨论】:

  • 试试after-validation-hook。检查后验证挂钩中所有 4 个字段的唯一性。
  • 好的,我正在尝试。但是somethingElseIsInvalid() 方法是占位符方法还是真的有目的?在 API 文档中找不到它。
  • 你想如何实现唯一规则?能举个例子吗?
  • 类似multicolumnunique:tablename,column1,column2,column3,column4
  • 那么你可以使用多个唯一规则。喜欢,unique:table1,column1|unique:table1,field2|unique:table1,field3。或者在验证后挂钩中,您必须在 somethingElseIsInvalid() 的位置实现 4 个字段的唯一性逻辑

标签: php laravel


【解决方案1】:

我是这样用的,

public function store(Request $req)
{
    $column1 = $req->input('column1');
    $column2 = $req->input('column2');
    $column3 = $req->input('column3');
    $column4 = $req->input('column4');


    $whereData = [
        ['column1', $column1],
        ['column2', $column2],
        ['column3', $column3],
        ['column4', $column4]
    ];

    $count = DB::table('yourtablename')->where($whereData)
                                ->count();

    if($count > 0){
        // The combined is not unique
        //send error message
    }else{
        //do whatever u need
    }

}

你也可以在AppServiceProvider的启动方法中实现这个。

将此代码添加到您的启动方法中:

Validator::extend('uniqueofFourColumns', function ($attribute, $value, $parameters, $validator) {

    $whereData = [
        ['column1', $value],
        ['column2', $parameters[0]],
        ['column3', $parameters[1]],
        ['column4', $parameters[2]]
    ];

    $count = DB::table('yourtablename')->where($whereData)->count();

    return $count === 0;
});

那么你可以在任何你需要的地方使用uniqueofFourColumns这个规则:

'column1' => 'uniqueofFourColumns:'.{{$request->column2}}.', '.{{$request->column3}}.', '.{{$request->column4}}

【讨论】:

  • 这不是一个真正的规则,这就是我打算在验证规则中做的事情。但我不知道该怎么做。
  • 谢谢@arun。有没有办法让列也动态?如果我没有为每个表使用相同的列名怎么办?
  • 为了让它更有活力,我可以建议修改一下吗?让我们将第一个参数作为 $tablename 发送:'column1' => uniqueofFourColumns:yourtablename'.{{$request->column2}}.', '.{{$request->column3}}.', '.... 然后在引导方法中:$count = DB::table($tablename)->where($whereData)->count();
猜你喜欢
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 2016-11-22
  • 2019-11-15
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
相关资源
最近更新 更多