Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

composite-unique-key-validation - laravel

seems it's not possible with built-in validators, how I should implement this feature in the model?

 $rules = [

            'user_id' => 'required|unique:service_details,user_id',
            'service_id'=>'required|unique:service_details,service_id'
         ];

above will prevent duplicacy of user_id and service_id independently which is not my requirement

it will reject

(1,2)
(1,3)

because 1 is duplicate but it should be accepted as i want composite unique key

like image 282
sumit Avatar asked Mar 17 '15 06:03

sumit


4 Answers

Composite unique field validation is provided out-of-the-box in 5.0+. I can't speak for earlier versions.

You can essentially specify a where clause for when your unique validation rule applies. E.g.

'term'  => 'unique:terms,term,NULL,id,taxonomy,category'

This rule says that term should be unique on the terms table but only where the taxonomy is equal to "category".

For example, it will prevent a "news" category being duplicated but I can still have a "news" tag.


I don't know your schema but in your case it'd be something like this:

$user_id = Request::get('user_id', $default);
$service_id = Request::get('service_id', $default);  
// or another way of specifying the accompanying service/user ID for the where clauses

$rules = [
    'user_id' => 'unique:service_details,user_id,NULL,id,service_id,' . $service_id;
    'service_id' => 'unique:service_details,service_id,NULL,id,user_id,' . $user_id;
];
like image 121
harryg Avatar answered Nov 11 '22 02:11

harryg


My solution

Laravel 5.3 and 5.4

Note: Without model binding

Store

'required',
Rule::unique('service_details','service_id')->where(function ($query) {
      $query->where('user_id', $this->request->get('user_id'));
})

Update

'required',
Rule::unique('service_details','service_id')->ignore($this->route()->id)->where(function ($query) {
      $query->where('user_id', $this->request->get('user_id'));
})
like image 31
ErcanE Avatar answered Nov 11 '22 02:11

ErcanE


This is not possible out of the box in Laravel. You would either have to write a custom validator or use a package for that.

Here is one that should do what you need: - https://github.com/felixkiss/uniquewith-validator

With this package, your rules could look like the following:

$rules = array(
    'user_id' => 'required|unique_with:service_details,service_id',
    'service_id' => 'required',
);

It works for both Laravel 4 and 5.

like image 7
nozzleman Avatar answered Nov 11 '22 02:11

nozzleman


With the help of this link , I am able to achieve composite validation from out of the box laravel 5.3. I knew it is old question and answered already. In my case vendor and client combination is unique.

My sample code is below

 $this->validate($request, [
        'Vendor'=> 'bail|required|int',
        'Client'=> 'bail|required|int',      
        'discount'=> 'required|numeric',            
        'Client'=>'unique:billings,client_id,vendor_id'.$request->Vendor
    ]);
like image 2
s vinayagam Avatar answered Nov 11 '22 02:11

s vinayagam