Niklesh Raut
Niklesh Raut

Reputation: 34914

Unique validation with category for insert and update in Laravel

I have list of items with related categories (table name is : 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

As In Laravel documention

Unique rule will not work here as for category wise, It validates name for all records.

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

How to validate items with related categories for insert and update in Laravel.

Upvotes: 4

Views: 4021

Answers (3)

Yury
Yury

Reputation: 109

If you have category_id in your request then this could work.

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

Upvotes: 1

linktoahref
linktoahref

Reputation: 7992

Create Custom Validation Rule

php artisan make:rule UniqueCategoryName

and change your validation rule as

use App\Rules\UniqueCategoryName;


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

and in the passes method of the Rule, do the validation against the table

<?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;
    }

}

Upvotes: 0

aleksejjj
aleksejjj

Reputation: 1835

I think you need something like

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

UPD: For update existing row:

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

Upvotes: 7

Related Questions