Уникальная проверка Laravel для нескольких столбцов

У меня есть 2 столбца в таблице серверов.

У меня есть колонки ip и hostname.

У меня есть подтверждение:

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

Это работает только для колонки ip. Но как сделать, чтобы он работал и для колонки hostname?

Я хочу проверить data.ip со столбцами ip и hostname. Потому что могут быть дубликаты в столбцах ip и hostname, когда пользователь пишет ip.

вам нужно проверить вместе уникальность для IP и имени хоста?

arun 15.05.2018 14:14

@arun Да. Имею 1 форму для ip. Когда пользователь пишет ip, мне нужно проверить этот ip в столбце ip и в имени хоста столбца .. если существует

Dumitru 15.05.2018 14:15

нет встроенной проверки, как то, что вы хотели. вы можете расширить его, см. stackoverflow.com/questions/50095328/…

arun 15.05.2018 14:17

@arun, а я могу так: 'data.ip' => ['required', 'unique:servers,ip,'.$this->id, 'unique:servers,hostname']?

Dumitru 15.05.2018 14:22

Выполните еще одну проверку поля отдельно, 'data.hostname' => ['required', 'unique:servers,hostname']

arun 15.05.2018 14:25

@arun нет, у меня нет входного имени хоста. Мне нужно проверить ввод IP в двух столбцах

Dumitru 15.05.2018 14:30

Попробуйте этот stackoverflow.com/questions/33855787/…

JYoThI 15.05.2018 14:33

Хотите чек по отдельности или вместе? Обновите свой вопрос со всей логикой?

Niklesh Raut 15.05.2018 14:34

@ C2486 обновленный вопрос ..

Dumitru 15.05.2018 14:36

У меня просто вопрос о том, как вы устранили проблему, в ответе, который вы проверили, у вас есть строка Rule :: unique ('servers') -> where (function ($ query) use ($ ip, $ hostname), и мне интересно если вы определили эти переменные ($ ip, $ hostname) где-то перед их использованием?

Red Eyez 18.02.2019 16:08

Ссылка на ссылку работает на 5.5 laravel.io/forum/…

Nirav Bhoi 21.07.2020 11:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
47
11
82 499
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Попробуйте это правило:
'data.ip' => 'required|unique:servers,ip,'.$this>id.'|unique:servers,hostname,'.$this->id

Следующее будет работать над созданием

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

и следующее для обновления

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

Я предполагаю, что id - ваш первичный ключ в таблице. Замените им свою среду.


(Недокументированный) формат уникального правила:

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

Можно указать несколько условий «где», но можно проверить только равенство. Закрытие (как в принятом ответе) необходимо для любых других сравнений.

Я использую индивидуальный запрос. И для магазина, и для обновления использую один и тот же запрос.

Dumitru 15.05.2018 14:52

Вам нужно будет уточнить, что вы имеете в виду под индивидуальным запросом. Затем для обновления и сохранения можно использовать один и тот же запрос, однако, если запрос содержит правила, у вас будет проблема с обновлением, если вы не проигнорируете запись в свою базу данных с текущим первичным ключом.

Leon Vismer 15.05.2018 15:15

Что делать, если значение содержит запятую?

Hlorofos 26.02.2019 14:18

Сомневаюсь, что нужен $request->input('id'). У меня ['column_1' => 'required|unique:TableName,column_1,' . $this->id . ',id,colum_2,' . $this->column_2] работает как для создания, так и для обновления.

O Connor 01.10.2019 16:44

Это именно то, что я искал, подробное объяснение и пример отсутствуют в официальных документах!

Tab Key 18.08.2020 06:31

Для меня это не работает для обновления. Я получил это `" title "=>" required | min: 2 | max: 255 | unique: terms, title, 20, id, type, listin‌ g-category "`. У меня не было записи с идентификатором 20 с таким же названием. И я пытаюсь отредактировать ту же запись, я имею в виду идентификатор с 20. Но это выдает мне ошибку вместо обновления. Хотя для создания он работает нормально

jayant rawat 01.02.2021 14:25

Мне нужно проверить уникальное условие, когда тип в таблице терминов является категорией листинга

jayant rawat 01.02.2021 14:26
Ответ принят как подходящий

Вы можете использовать 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
);

изменить: фиксированное назначение сообщения

абсолютно идеальное решение, но также необходимо обновить операцию.

Razib Al Mamun 02.01.2019 11:57

Я пробовал нечто подобное, но при использовании "use ($ variable1, $ variable2)" у меня была неопределенная переменная. мне нужно где-то их определять?

Red Eyez 18.02.2019 16:02

Используйте это так: `$ text = $ this-> request-> text; $ branch_id = $ this-> request-> branch_id; $ validator = \ Validator :: make ($ this-> request-> all (), array ('text' => ['required', Rule :: unique ('cpl_tax') -> где (функция ($ query) use ($ text, $ branch_id) {return $ query-> where ('text', $ text) -> where ('branch_id', $ branch_id);}),],)); `@RedEyez

maruf najm 22.08.2019 09:05

@RazibAlMamun Для обновления используйте этот $text = $this->request->text; $branch_id = $this->request->branch_id; $tax_id = $this->request->tax_id; $validator = \Validator::make($this->request->all(), array( 'text' => [ 'required', Rule::unique('cpl_tax')->where(function ($query) use($tax_id, $text, $branch_id) { return $query->where('text', $text) ->where('branch_id', $branch_id)->where('tax_id', '!=', $tax_id); }), ], ));

maruf najm 22.08.2019 09:15

Для обновления используйте ingore. ->ignore($serverid); смотри ответ stackoverflow.com/a/58028505/9978078

Dilip Hirapara 04.11.2019 06:41

Laravel 5.6 и выше

Проверка в контроллере

Первичный ключ (в моем случае) представляет собой комбинацию двух столбцов (название, guard_name)

Я проверяю их уникальность, используя класс Правило как в Создайте, так и в методе Обновить моего контроллера (PermissionsController)


PermissionsController.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');
    }
}

Обратите внимание, что в методе обновления я добавил дополнительное ограничение запроса [whereNotIn ('id', [$ permission-> id])], чтобы игнорировать текущую модель.


ресурсы / язык / en / messages.php

<?php

return [

    'permission' => [

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

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

Метод flash () взят из пакета ларакасты / вспышка.

абсолютно идеальное решение

Razib Al Mamun 02.01.2019 11:56

Это определенно должен быть принятый ответ. Включение пользовательских сообщений об ошибках в языковые файлы делает его действительно гибким и обеспечивает отличную обратную связь. Спасибо

Mat 21.01.2019 17:38

Таблица

server

Поле

  • id primary key

  • ip should be unique with hostname

  • hostname should be unique with ip

Здесь я проверяю IP, и имя хоста должно быть уникальным.

use Illuminate\Validation\Rule;

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

Пока создаете

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

Пока обновление

Добавить игнорирование после 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);
    ],
]);

Я думаю, при обновлении он игнорирует условие where в моем случае. Я dd () условие и получил это. Illuminate\Validation\Rules\Unique {#1871 ▼ #ignore: "10" #idColumn: "id" #table: "term" #column: "NULL" #wheres: array:1 [▼ 0 => array:2 [▼ "column" => "type" "value" => "list-cat" ] ] #using: [] } Но вообще не работает при обновлении.

jayant rawat 01.02.2021 14:31

В таблице есть одноименная категория. Но тип другой

jayant rawat 01.02.2021 14:32

Примечание: я использую Laravel 5.8

jayant rawat 01.02.2021 14:33

У меня это работает как для создания, так и для обновления.

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

Примечание: протестировано в Laravel 6.

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.',
            ]
        );

Это демонстрационный код. Это помогло бы вам намного лучше. Я попытался охватить как сценарии вставки, так и обновления.

Внутри приложение / 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;
    });

Внутри приложение / 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'
    ];
}

Внутри приложение / 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'
    ];
}

Внутри ресурсы / lang / en / validation.php

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

Здесь, в этом коде, используется пользовательская проверка uniqueOfMultiple. Первым переданным аргументом является имя_таблицы, то есть menus, а все остальные аргументы - имя_столбца и разделены запятыми. Здесь используются столбцы: name (основной столбец), location_id, language_id и один столбец, за исключением столбца для случая обновления, except-id. Значение, переданное для всех трех, разделено -.

Это сработало для меня (уникально по movie_id, act_id, name): (Laravel версии 7.x)

/**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'movie_id' => 'required',
            'actor_id' => 'required',
            'name' => [
                'required',
                'string',
                'min:1',
                'max:255',
                Rule::unique('movie_characters')
                ->where('movie_id',$this->request->get('movie_id'))
                ->where('actor_id',$this->request->get('actor_id'))
            ]
            
        ];
    }

С запросами формы:

В StoreServerRequest (для создания)

public function rules() {
    'ip' => [
        'required',
         Rule::unique('server')->where(function ($query) {
             $query->where('ip', $this->ip)
                ->where('hostname', $this->host);
         })
    ],
}

public function messages() {
    return [
       'ip.unique' => 'Combination of IP & Hostname is not unique',
    ];
}

В UpdateServerRequest (для обновления)

Просто добавьте игнорирование в конце

public function rules() {
    'ip' => [
        'required',
         Rule::unique('server')->where(function ($query) {
             $query->where('ip', $this->ip)
                ->where('hostname', $this->host);
         })->ignore($this->server->id)
    ],
}

Другие вопросы по теме