php Laravel 对多列的唯一验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50349775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:49:15  来源:igfitidea点击:

Laravel unique validation on multiple columns

phplaravel

提问by Dumitru

I have 2 columns in table servers.

我在表服务器中有 2 列。

I have columns ipand hostname.

我有列iphostname.

I have validation:

我有验证:

'data.ip' => ['required', 'unique:servers,ip,'.$this->id]

This working only for column ip. But how to do that it would work and for column hostname?

这仅适用于 column ip。但是如何做到这一点,它会起作用并且对于 columnhostname呢?

I want validate data.ip with columns ipand hostname. Because can be duplicates in columns ip and hostname, when user write ip.

我想用列iphostname. 因为在列ip和hostname中可以重复,当用户写ip时。

回答by Niklesh Raut

You can use Rule::uniqueto achieve your validation rule

您可以使用Rule::unique来实现您的验证规则

$messages = [
    'data.ip.unique' = 'Given ip and hostname are not unique',
];

Validator::make($data, [
    'data.ip' => [
        'required',
        Rule::unique('servers')->where(function ($query) use($ip,$hostname) {
            return $query->where('ip', $ip)
            ->where('hostname', $hostname);
        }),
    ],
],
$messages
);

回答by Leon Vismer

The following will work on the create

以下将适用于创建

'data.ip' => ['required', 'unique:servers,ip,'.$this->id.',NULL,id,hostname,'.$request->input('hostname')]

and the following for the update

以及以下更新

'data.ip' => ['required', 'unique:servers,ip,'.$this->id.','.$request->input('id').',id,hostname,'.$request->input('hostname')]

I'm presuming that idis your primary key in the table. Substitute it for your environment.

我假设这id是您在表中的主键。将其替换为您的环境。



The (undocumented) format for the unique rule is:

唯一规则的(未记录的)格式是:

table[,column[,ignore value[,ignore column[,where column,where value]...]]]

[,[,忽略值[,忽略列[,其中列其中值]...]]]

Multiple "where" conditions can be specified, but only equality can be checked. A closure (as in the accepted answer) is needed for any other comparisons.

可以指定多个“where”条件,但只能检查相等性。任何其他比较都需要闭包(如已接受的答案)。

回答by chebaby

Laravel 5.6 and above

Laravel 5.6 及以上

Validation in the controller

控制器中的验证

The primary key (in my case) is a combination of two columns (name, guard_name)

主键(在我的情况下)是两列(nameguard_name)的组合

I validate their uniqueness by using the Ruleclass both on createand on updatemethod of my controller (PermissionsController)

我通过在控制器 ( PermissionsController) 的createupdate方法上使用Rule类来验证它们的唯一性



PermissionsController.php

权限控制器.php

<?php

namespace App\Http\Controllers;

use App\Permission;

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;

class PermissionsController extends Controller
{

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        request()->validate([

            'name'        => 'required|max:255',

            'guard_name'  => [

                'required', 

                Rule::unique('permissions')->where(function ($query) use ($request) {

                    return $query
                        ->whereName($request->name)
                        ->whereGuardName($request->guard_name);
                }),
            ],
        ],
        [
            'guard_name.unique' => __('messages.permission.error.unique', [

                'name'              => $request->name, 
                'guard_name'        => $request->guard_name
            ]),
        ]);

        Permission::create($request->all());

        flash(__('messages.permission.flash.created'))->success();

        return redirect()->route('permission.index');
    }


    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, Permission $permission)
    {
        request()->validate([

            'name'        => 'required|max:255',

            'guard_name'  => [

                'required', 

                Rule::unique('permissions')->where(function ($query) use ($request, $permission) {

                    return $query
                        ->whereName($request->name)
                        ->whereGuardName($request->guard_name)
                        ->whereNotIn('id', [$permission->id]);
                }),
            ],
        ],
        [
            'guard_name.unique' => __('messages.permission.error.unique', [

                'name'              => $request->name, 
                'guard_name'        => $request->guard_name
            ]),
        ]);

        $permission->update($request->all());

        flash(__('messages.permission.flash.updated'))->success();

        return redirect()->route('permission.index');
    }
}

Notice in the update method i added an additional query constraint [ whereNotIn('id', [$permission->id])] to ignore the current model.

请注意,在更新方法中,我添加了一个额外的查询约束 [ whereNotIn('id', [$permission->id])] 以忽略当前模型。



resources/lang/en/messages.php

资源/lang/en/messages.php

<?php

return [

    'permission' => [

        'error' => [
            'unique' => 'The combination [":name", ":guard_name"] already exists',
        ],

        'flash' => [
            'updated' => '...',
            'created' => '...',
        ],
    ]
]


The flash() method is from the laracasts/flashpackage.

flash() 方法来自laracasts/flash包。

回答by vpalade

Try this rule:
'data.ip' => 'required|unique:servers,ip,'.$this>id.'|unique:servers,hostname,'.$this->id

试试这个规则:
'data.ip' => 'required|unique:servers,ip,'.$this>id.'|unique:servers,hostname,'.$this->id

回答by Dilip Hirapara

Table

桌子

server

服务器

Field

场地

  • id primary key

  • ip should be unique with hostname

  • hostname should be unique with ip

  • ID primary key

  • ip should be unique with hostname

  • 主机名 should be unique with ip

Here I validate for Ip and the hostname should be unique.

在这里,我验证了 Ip 并且主机名应该是唯一的。

use Illuminate\Validation\Rule;

$ip = '192.168.0.1';
$host = 'localhost';

While Create

创建时

Validator::make($data, [
    'ip' => [
        'required',
         Rule::unique('server')->where(function ($query) use($ip,$host) {
           return $query->where('ip', $ip)->where('hostname', $host);
         });
    ],
]);

While Update

虽然更新

Add ignore after RULE

在后面添加忽略 RULE

Validator::make($data, [
    'ip' => [
        'required',
         Rule::unique('server')->where(function ($query) use($ip,$host) {
           return $query->where('ip', $ip)->where('hostname', $host);
         })->ignore($serverid);
    ],
]);

回答by O Connor

This works for me for both create and update.

这对我来说既适用于创建又适用于更新。

[
     'column_1' => 'required|unique:TableName,column_1,' . $this->id . ',id,colum_2,' . $this->column_2
]

Note: tested in Laravel 6.

注意:在 Laravel 6 中测试。

回答by Ankit Singh

This is the demo code. It would help you much better. I tried covering both insert and update scenarios.

这是演示代码。它会更好地帮助你。我尝试涵盖插入和更新场景。

Inside app/Http/Providers/AppServiceProvider.php

app/Http/Providers/AppServiceProvider.php 里面

Validator::extend('uniqueOfMultiple', function ($attribute, $value, $parameters, $validator)
    {
        $whereData = [
            [$attribute, $value]
        ];

        foreach ($parameters as $key => $parameter) {

            //At 0th index, we have table name
            if(!$key) continue;

            $arr = explode('-', $parameter);

            if($arr[0] == 'except') {
                $column = $arr[1];
                $data = $arr[2];

                $whereData[] = [$column, '<>', $data];
            } else {
                $column = $arr[0];
                $data = $arr[1];

                $whereData[] = [$column, $data];
            }
        }

        $count = DB::table($parameters[0])->where($whereData)->count();
        return $count === 0;
    });

Inside app/Http/Requests/Something/StoreSometing.php

app/Http/Requests/Something/StoreSometing.php 中

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'name' => 'required|max:225|uniqueOfMultiple:menus,location_id-' . $this->get('location_id', 'NULL') . ',language_id-' . $this->get('language_id', 1),
        'location_id' => 'required|exists:menu_location,id',
        'order' => 'digits_between:0,10'
    ];
}

Inside app/Http/Requests/Something/UpdateSomething.php

app/Http/Requests/Something/UpdateSomething.php 中

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'name' => 'required|max:225|uniqueOfMultiple:menus,location_id-' . $this->get('location_id', 'NULL') . ',language_id-' . $this->get('language_id', 'NULL') . ',except-id-' . $this->route('id', 'NULL'),
        'location_id' => 'required|exists:menu_location,id',
        'order' => 'digits_between:0,10'
    ];
}

Inside resources/lang/en/validation.php

里面resources/lang/en/validation.php

'unique_of_multiple' => 'The :attribute has already been taken under it\'s parent.',

Here in this code, the custom validation used is uniqueOfMultiple. The first argument passed is the table_name i.e menusand all other arguments are column_name and are comma-separated. The columns are used here, name(primary column), location_id, language_idand one except-for column for the update case, except-id. The value passed for all three is -separated.

在此代码中,使用的自定义验证是uniqueOfMultiple. 传递的第一个参数是 table_name ie menus,所有其他参数都是 column_name 并且以逗号分隔。此处使用的列name(primary column) location_id,language_id和一个用于更新案例的 except-for 列except-id. 为所有三个传递的值是-分开的。

回答by zhan

public function store(Request $request)
    {
         $this->validate($request, [
            'first_name' => 'required|regex:/^[\pL\s\-]+$/u|max:255|unique:contacts,first_name, NULL,id,first_name,'.$request->input('last_name','id'),
            'last_name'=>'required|regex:/^[\pL\s\-]+$/u|max:255|unique:contacts,last_name',
            'email' => 'required|email|max:255|unique:contacts,email',
            'job_title'=>'required',
            'city'=>'required',
            'country'=>'required'],
            [
             'first_name.regex'=>'Use Alphabets Only',
             'email.unique'=>'Email is Already Taken.Use Another Email',
             'last_name.unique'=>'Contact Already Exist!. Try Again.',
            ]
        );