Reputation: 34914
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
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
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
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