问题
I have an API that sends an array of staff, some are existing objects that need to be updated and some are new objects that need to be created, they all need to be validated and as part of that is testing for a unique email. I am using a FormRequest:
$rules = [
'staff.*.name' => 'required|max:128',
'staff.*.email' => 'required|email|unique:users',
'staff.*.description' => 'max:512',
];
So the problem is, as I am sure you can see, the email address fails unique validation on update. This is because the mechanism for ignoring the email if the ID is the same as the item being validated is causing me an issue.
I can not see a way of getting the ID of the object currently being validated so I can access its ID. So I can't add the part:
'staff.*.email' => 'required|email|unique:users,email,id,' . $currentStaff->id
I can't see much about this specific issue so I am assuming I am barking up the wrong tree doing it this way or missing something insanely obvious.
The payload below:
{
"staff": [
{
"name":"Libbie Turcotte",
"email":"carolyn16@example.net",
"updated_at":"2019-12-05 19:28:59",
"created_at":"2019-12-05 19:28:59",
"id":53
},
{
"name":"Person Dave",
"email":"dave@email.com",
},
{
"name":"Staff Name",
"email":"staff@email.com",
}
]
}
回答1:
You can add the rules foreach request staff element looping through the array and merging the corresponding rule:
$rules = [ // this ones are ok for all
'staff.*.name' => 'required|max:128',
'staff.*.description' => 'max:512',
];
// here loop through the staff array to add the ignore
foreach($request->staff as $key => $staff) {
if ( array_key_exists('id', $staff) && $staff['id'] ) { // if have an id, means an update, so add the id to ignore
$rules = array_merge($rules, ['staff.'.$key.'.email' => 'required|email|unique:users,id,'.$staff['id']]);
} else { // just check if the email it's not unique
$rules = array_merge($rules, ['staff.'.$key.'.email' => 'required|email|unique:users']);
}
}
So, for this request
staff[1][id]=111
staff[1][email]=dd@ddd.dd
staff[2][id]=222
staff[2][email]=eee@eee.ee
staff[3][email]=fff@ffff
You will have this rules:
[
"staff.*.name" => "required|max:128",
"staff.*.description" => "max:512",
"staff.1.email": "required|email|unique:users,id,111",
"staff.2.email": "required|email|unique:users,id,222",
"staff.3.email": "required|email|unique:users"
]
回答2:
You can use just 'distinct' as like:
'staff.*.email' => 'distinct',
来源:https://stackoverflow.com/questions/59197360/laravel-validation-unique-failing-on-update-for-array-of-object