Intead of this line
return $this->error($import->failures(), 422);
save it to the database?
https://docs.laravel-excel.com/3.1/imports/validation.html#gathering-all-failures-at-the-end
In my Laravel-8, I am uploading from Excel into the DB using Maatwebsite package:
Import:
In my Laravel-8 and Maatwebsite-3.1 package, I have this code:
use App\Models\User;
use App\Models\Country;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\SkipsErrors;
use Maatwebsite\Excel\Concerns\SkipsOnError;
use Maatwebsite\Excel\Concerns\SkipsFailures;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Validators\Failure;
use Throwable;
class CountryImport implements
ToModel,
WithValidation,
WithHeadingRow,
SkipsOnError,
SkipsOnFailure,
WithBatchInserts
{
use Importable, SkipsErrors, SkipsFailures;
public function model(array $row)
{
return new Country([
'name' => $row['name],
'nationality' => $row['nationality],
'created_at' => date("Y-m-d H:i:s"),
'created_by' => Auth::user()->id,
]);
}
public function headingRow(): int
{
return 1;
}
public function rules(): array
{
return [
'*.name' => [
'required',
'string',
'max:100',
Rule::unique('countries', 'name')
],
'*.nationality' => [
'nullable',
'string',
'max:50',
Rule::unique('countries', 'nationality')
],
];
}
public function batchSize(): int
{
return 1000;
}
public function chunkSize(): int
{
return 1000;
}
}
Controller:
public function importCountry(Request $request)
{
$user = Auth::user()->id;
$userEmail = Auth::user()->email;
$file = $request->file('document')->store('import');
$import = new CountryImport;
$import->import($file);
if($import->failures()->isNotEmpty())
{
return $this->error($import->failures(), 422);
}
dd($import->failures());
return $this->success('Nationalities Successfully Imported.', [
'file' => $file
]);
}
I made the upload to skip failures and errors during upload.
return $this->error($import->failures(), 422);
gives:
{
"message": [
{
"row": 2,
"attribute": "Country",
"errors": [
"The Country has already been taken."
],
"values": {
"country_name_full": "Afghanistan",
"nationality": "Afghan",
}
},
{
"row": 3,
"attribute": "Country",
"errors": [
"The Country has already been taken."
],
"values": {
"country_name_full": "Albania",
"nationality": "Albanian",
}
}
],
"error": true,
"code": 422
}
while dd($import->failures());
gives:
Illuminate\Support\Collection {#1542
#items: array:184 [
0 => Maatwebsite\Excel\Validators\Failure {#2917605
#row: 2
#attribute: "Country"
#errors: array:1 [
0 => "The Country has already been taken."
]
-values: array:7 [
"name" => "Afghanistan"
"nationality" => "Afghan"
"" => null
]
}
1 => Maatwebsite\Excel\Validators\Failure {#2933982
#row: 3
#attribute: "Country"
#errors: array:1 [
0 => "The Country has already been taken."
]
-values: array:7 [
"name" => "Albania"
"nationality" => "Albanian"
"" => null
]
}
I have a Model called ImportError with these fields
ImportError (row, attribute, error, values)
Since I allow SkipOnFailure and SkipOnError. In the same controller, how do I automatically store these errors in the ImportError Models immediately After Import so that users can access it later?
Intead of this line
return $this->error($import->failures(), 422);
save it to the database?
https://docs.laravel-excel.com/3.1/imports/validation.html#gathering-all-failures-at-the-end
Please or to participate in this conversation.