Laravel-Excel: Only one failure returned when using WithValidation concern
Prerequisites
- Able to reproduce the behaviour outside of your code, the problem is isolated to Laravel Excel.
- Checked that your issue isn’t already filed.
- Checked if no PR was submitted that fixes this problem.
Versions
- PHP version: 7.1.18
- Laravel version: 5.7.13
- Package version: 3.1.3
Description
I’m working on an Import class that uses concerns WithHeadingRow and WithValidation. I’ve copied the try/catch in the docs for gathering failures, but it is only catching one failure at a time (an array with one entry), rather than gathering all validation errors for all rows into an array, as the documentation says. The import is otherwise working as expected, and it is validating correctly, but apparently stopping after the first validation failure.
Steps to Reproduce
Relevant controller code:
try {
Excel::import(new MaterialHazardImport(), $path);
} catch (\Maatwebsite\Excel\Validators\ValidationException $e) {
$failures = $e->failures();
return view('admin.material-hazard-import.errors', compact('failures'));
}
Relevant import class code:
<?php
namespace App\Imports;
use App\Models\MaterialHazardImportTask;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
class MaterialHazardImport implements ToModel, WithHeadingRow, WithValidation
{
public function model(array $row)
{
if (isset($row['casrn_or_material_id'])) {
return new MaterialHazardImportTask([
'hazard_id' => $row['hazard_id'],
'casrn' => $row['casrn_or_material_id'],
'name' => $row['chemical_or_material_name'],
]);
}
}
public function rules(): array
{
return [
'hazard_id' => 'required',
'casrn_or_material_id' => 'required',
'chemical_or_material_name' => 'required',
];
}
}
Expected behavior:
Uploading a template with multiple rows that have “chemical_or_material_name” missing should yield a $failures array with multiple entries.
Actual behavior:
Only one failure is returned in the array, as shown in my errors view. Example below:
Additional Information
Any additional information, configuration or data that might be necessary to reproduce the issue.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 19 (9 by maintainers)
If you want to catch all validation errors, you need to use batch inserts. Without it, it will validate row per row.
Without implementing skipsOnFailure
Implementing skipsOnFailure
Batch inserts are meant to avoid repeating an unnecessary amount of queries. At the same time, in case of any failure the batch currently running will be rolledback along with the previous ones, and without having to read the subsequent ones.
So the only way to insert all the valid rows and keep track of all the failures, is loading the whole file, implementing skipsOnFailure and saving each failure to retrieve them later via a getter. In this case batchInserts would just do the favor of avoiding possible bottleneck effect.
Please clarify or confirm if i’m getting it right. PD: I know about the trait that is now available.
@Nutbolt52 Thanks for your PR by the way 😉
Thank you @patrickbrouwers! That seems to have solved it, and when you put it like that, it kind of makes sense why it works that way now. Maybe just a note in the documentation for the idiots out there like me 😃.
So just to make sure I am 100% understanding, if I have batch size set to 100, it will only show validation issues on the first 100 rows, I won’t see any validation issues on the rows 100+ in the next batch?