Laravel 5 multiple table unique validation - php

For example, I have 2 tables : sites1 and sites2
I need to check that field url which is comes from my html form is unique.
Here my validation rule :
public function rules()
{
return [
'url' => unique:sites1|unique:sites2'
];
}
Unfortunately, this rule applies only for sites2 table. Is there any possible ways to validate both tables?

Your validation rule seems ok. Just make sure that both sites1 and sites2 table has field name url and both in same database.
Your unique:sites1 rule will be translated into SQL
select count(*) as aggregate from `sites1` where `url` = ?
While unique:sites2 rule will be translated into SQL
select count(*) as aggregate from `sites2` where `url` = ?
See if first SQL does return result. Long URL may result non unique if used with limited index length. It may be better if you could store hash value of URL so you can compare url just by using hash.

No need to maintain the same name in two different tables
In laravel 4.2
Validator::make(Input::all, [
'url' => 'unique:site1,your_column_name|unique:site2:your_column_name_2'
]);
Laravel 5.*:
$this->validate($request,[
'url' => 'unique:site1,your_column_name|unique:site2:your_column_name_2'
]);
Hopefully it's working fine.

In the above answer i think you can't use custom error message, you can do in another way just copy the filed in another field for the two checks.
public function validator(array $data)
{
$data = ['url2' => $data['email']];
$rules = [
'url' => 'unique:sites1',
'url2' => 'unique:sites2',
];
$messages = [
'url.unique' => 'url unique in site 1',
'url2.unique' => 'url unique in site 2',
];
return $validator = Validator::make($data, $rules, $messages);
}
if ($validator->fails()) {
if(!empty($validator->errors()->get('url2'))) {
$validator->errors()->add("url", 'url unique in site 2');
}
}

Related

Laravel validation: exists two column same row

Is there a way of referencing another field when specifying the exists validation rule in Laravel?
My request :
public function rules()
{
return [
'numero_de_somme' => 'unique:personnels,numero_de_somme|exists:fonctionnaire,num_somme',
'cin' => 'unique:personnels,cin|exists:fonctionnaire,cin',
];
}
in my validation rules I want to be able to make sure that:
num_somme exists within the fonctionnaire table
cin exists within the fonctionnaire table and cin input must be
on the same row of the num_somme
num_somme : 12345 cin : s89745
num_somme : 78945 cin : U10125
Explaining : for example
1st scenario if the input num_somme = 12345 and cin = U10125 the validation must fail
2nd scenario if the input num_somme = 12345 and cin = s89745 the validation must success
I hope this makes sense.
Thank you
You can simply use this:
'request_input' => exists:table,col,alternative_col_1,alternative_val_1,alternative_col_2,alternative_val_2, ...'
The SQL query is like below:
select count(*) as aggregate from `table` where `id` = [request_input] and `alternative_col1` = "alternative_val1" and `alternative_col2` = "alternative_val2"
I came across the same need today and I think I have a solution using the validation Rule class: Rule example.
Here is my scenario: I have an email verifications table and I want to ensure that a passed machine code and activation code exist on the same row.
Be sure to include use Illuminate\Validation\Rule;
$activationCode = $request->activation_code;
$rules = [
'mc' => [
'required',
Rule::exists('email_verifications', 'machineCode')
->where(function ($query) use ($activationCode) {
$query->where('activationCode', $activationCode);
}),
],
'activation_code' => 'required|integer|min:5',
'operating_system' => 'required|alpha_num|max:45'
];
The first argument in the exists method is the table and the second is the custom column name I'm using for the 'mc' field. I pass the second column I want to check using the 'use' keyword and then use that field in a a where clause.
You can achieve validating multipe columns by using Rule.
Include :
use Illuminate\Validation\Rule;
use Validator;
$AdminId = $request->AdminId;
$Validate = Validator::make($request->all(),[
'TaxId' => [ 'required', Rule::exists('tax','id')
->where(function ($query) use ($AdminId) {
$query->where('u_id', $AdminId);
})],
]);
if($Validate->fails())
{`Your ERROR HERE`}
else
{`SUCCESS`}
Here in my example I'm checking u_id and Id which is in same row and 2 columns.
Explaining : for example
My DB HAS 2 ROWS IN tax TABLE
id = 1 , u_id = 1, tax = "GST" , value -> 8
id = 2 , u_id = 2, tax = "GST" , value -> 5
1st scenario if the input id = 2 and u_id = 1 the validation must fail because this row belongs to u_id = 2.
2nd scenario if the input id = 2 and u_id = 2 the validation must success
i managed to solve it using the most simple method
for numero_de_somme
'numero_de_somme' => 'unique:personnels,numero_de_somme|exists:fonctionnaire,num_somme,cin,'.Request::get('cin'),
for cin
'cin' => 'unique:personnels,cin|exists:fonctionnaire,cin',
PS . don't forget to call use Illuminate\Http\Request;
if (is_numeric($request->get('emailOrphone'))){
$request->validate([
'emailOrphone'=>'exists:users,phone',
],
[
'emailOrphone.exists'=>'phone is invalid.'
]);
}else{
$request->validate([
'emailOrphone'=>'exists:users,email',
],
[
'emailOrphone.exists'=>'email is invalid.''
]);
}

Laravel 5.3 Validation: Unique period time which is set by two column (start_date, end_date)

Is there any way to validate the unique period times which is set by two column (start_date, end_date)? Please let me know if this is possible by using Laravel 5.3 validator.
Thanks
Arvi
So far as I know there is no way to accomplish such complex custom rules on Laravel. I understand that you really wanna do some thing like this:
//////////////////////////////////////////////////
// This is not working code. just an idea !!!
//
$data['period'] = $data['start_date'] . "-" . $data['end_date'];
$validator = Validator::make($data, [
'period' => Rule::unique('projects', DB::raw('concat(start_date, "-", end_date)')),
], [
'period' => 'Period is duplicated.',
]);
But Larvel does not accept this kind of rule (actually I am wondering why they do not accept this kind of approach)
So you have 2 options.
Solution 1. Create a view in the database, which will have additional column "period" which is made by concat(start_date,"-",end_date).
And then make the code like following.
$data['period'] = $data['start_date'] . "-" . $data['end_date'];
$validator = Validator::make($data, [
'period' => Rule::unique('projects', DB::raw('concat(start_date, "-", end_date)')),
], [
'period' => 'Period is duplicated.',
]);
if ($validator->fails()) {
// do some thing
} else {
unset($data['period']); // When adding or update, 'period' will cause error because period is only in view, not in table itself
// do insert or update
}
Solution 2. Just pass normal validation except for the unique checking, after all validation done, you do checking yourself by searching in the table manually.
Like following:
if (Project::where(DB::raw("concat(start_date, '-', end_date)"), "=", $data['start_date'] . "-" . $data['end_date'])->count() > 0) {
// now this is not unique, so do something
}

Is there a way to check if a couple of inputs are unique in laravel 5.2?

update
What I have is a table with these columns:
- ID
- production_year
- type
If the type is already present in the table with the value the user wants to pass, check if production_year is already present too, but fail the validation ONLY if these values are present in the same record. Otherwise let the user to store this record.
I'm trying to check the uniqueness of a couple of fields in the same record...
I've seen the documentation about the conditional validation, but I didn't quite find the answer there.
the code
public function rules()
{
return [
// I'd like to check the uniqueness of both of them. In the same record
'production_y' => 'required|unique',
'fk_type' => 'required|unique',
];
}
Any idea? Thanks!
Laravel 5.3 Update:
Now, you can generate the same rule fluently using the Rule (\Illuminate\Validation\Rule) class.
NULL,id part of the string way is no more required. See:
public function rules()
{
$type = $this->get('fk_type');
return [
'production_y' => [
'required',
Rule::unique('your_table', 'production_year')->where(function($query) {
$query->where('type', $type);
}),
],
];
}
Original Answer
Can't test right now, can you try:
public function rules()
{
$type = $this->get('fk_type');
return [
'production_y' => "required|unique:your_table,production_year,NULL,id,type,{$type}",
// ...
];
}
Explaination:
unique:your_table Set the table for the unique check.
,production_year This matches with production_y.
,NULL,id check all the records.
3.1. if you use like {$id},id it will check uniqueness except the record with the {$id},
,type,{$type} and the type should be {$type}
That will produce sth. like (not exact query, just to express the idea):
select count(*) from your_table where production_year = $product_y and where type = $type and where id <> null
if someone cames from laravel 8, i tried this and it worked !!
for me i need to check the uniqueness of (category_id,subcategory_id) which mean you can find (1,2),(1,3),(2,1),(2,3) but you cant find similar couple !!
'category' => "required|unique:tickets,category_id,NULL,id,subcategory_id,{$request->input('subcategory')}"

Not getting the id in where clause - Laravel 5.2

I need to get the record with special id and i have this in my method :
public function addedMark()
{
$user = Auth::user();
$subject = ClassSubject::where('teacher_id', $user->id)->pluck('id','subject_id');
return view('educator.account.marks', [
'user' => $user,
'marks' => StudentMark::where('subject_id', $subject)->get()
]);
}
When i do dd(ClassSubject::where('teacher_id', $user->id)->pluck('id','subject_id')); i see that I'm getting the information that i need, but when i do dd(StudentMark::where('subject_id', $subject)->get()); it returns an empty array.
Any idea why?
Change it to (whereIn)
'marks' => StudentMark::whereIn('subject_id', $subject)->get()
and let see what hapens
In $subjectyou have id and subject_id. You might wanna just take subject_id.
So change this: StudentMark::where('subject_id', $subject)->get()
to
StudentMark::where('subject_id', $subject[1])->get()

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

Categories