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


У меня есть список элементов со связанными категориями (имя таблицы : items)

--- id ------ category_id ----- name
--- 1 ------- 1 ---------------- aa  --> Valid
--- 2 ------- 1 ---------------- bb  --> Valid
--- 3 ------- 2 ---------------- aa  --> Valid
--- 4 ------- 2 ---------------- bb  --> Valid
--- 5 ------- 1 ---------------- aa  --> InValid because same name exist in same category
--- 6 ------- 2 ---------------- bb  --> InValid because same name exist in same category

Как в Laravel documentation

Уникальное правило здесь не будет работать, так как для категории wise оно проверяет name для всех записей.

public function validateItems($requestAll){
    $id = isset($requestAll['id']) ? ','.$requestAll['id'].',id':'';
    $rules = [
        'name' => 'required|unique:items,name'.$id,
        'category' => 'required'
    ];
    return Validator::make($requestAll, $rules);
}

Как проверить элементы со связанными категориями для вставки и обновления в Laravel.

3 2

3 ответа:

Я думаю, вам нужно что-то вроде

'name' => Rule::unique('items')->where(function ($query) use ($categoryId) {
    return $query->where('category_id', $categoryId);
}),

UPD: для обновления существующей строки:

'name' => Rule::unique('items')->ignore($existingRecordId)->where(function ($query) use ($categoryId) {
    return $query->where('category_id', $categoryId);
}),

Если у вас есть category_id в вашем запросе, то это может сработать.

public function validateItems($requestAll){
   $id = isset($requestAll['id']) ? $requestAll['id'] : 'NULL'; //with PHP7 it could be $id = $requestAll['id'] ?? 'NULL';
   $categoryId = $requestAll['category_id']; //i don't know if it exists in your request.
   $rules = [
      'name' => 'required|unique:items,name,'.$id.',id,category_id,'.$categoryId,
      'category' => 'required'
   ];
   return Validator::make($requestAll, $rules);
}

Создание Пользовательского Правила Проверки

php artisan make:rule UniqueCategoryName

И измените правило проверки на

use App\Rules\UniqueCategoryName;


'name' => ['required', new UniqueCategoryName($category_id)],

И в методе passes правила выполните проверку по таблице

<?php

namespace App\Rules;

use App\Item;
use Illuminate\Contracts\Validation\Rule;

class UniqueCategoryName implements Rule
{

    protected $category_id;

    public function __construct($category_id) {
        $this->category_id = $category_id;
    }

    public function passes($attribute, $value)
    {
        $items = Item::where([
                       ['category_id', $this->category_id],
                       ['name', $value]
                 ])->get();

        if ($items->count()) {
            return false;
        }

        return true;
    }

}