¿Cómo mostrar un mensaje de validación si el campo de nombre está duplicado en el archivo cargado?
<?php namespace App\Imports; use App\Models\Customer; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\WithHeadingRow; use Maatwebsite\Excel\Concerns\WithValidation; class CustomerImport implements ToCollection, WithHeadingRow, WithValidation { public $timestamps = false; public function collection(Collection $rows) { foreach ($rows as $row) { Customer::create([ 'name' => $row['name'], 'address' => $row['address'], ]); } } public function rules(): array { return [ 'name' => [ 'required', 'max:50', 'unique:customers,name', ], 'address' => [ 'required', 'max:50', 'unique:customers,address', ] ]; } }Mi archivo csv cargado de muestra es el siguiente: El nombre 'AAA' está duplicado. Por lo tanto, necesito que se muestre un mensaje de error de validación para una entrada duplicada en el archivo.
Nombre dirección
AAA, dirección de prueba
AAA, dirección de prueba1
BBB,dirección2
En este momento estoy recibiendo Illuminate\Database\QueryException SQLSTATE[23000]: Infracción de restricción de integridad: 1062 Error de entrada duplicada 'AAA'.
El código de mi controlador es el siguiente:
public function uploadFile(Request $request) { $request->validate( ['file' => ['required', 'file', 'mimes:txt,csv']], ['file.required' => 'Please upload the file'] ); try { Excel::import(new CustomerImport(), $request->file('file')); } catch (\Maatwebsite\Excel\Validators\ValidationException $e) { $failures = $e->failures(); return redirect() ->route('customers.upload') ->withErrors($failures); } return redirect() ->route('customers.index') ->with('success', __('customers.message_uploaded')); }Puede lograr esto creando una regla de validación personalizada. Un ejemplo de implementación utilizando la biblioteca Maatwebsite puede ser:
app\Rules\CsvUnique.php namespace App\Rules; use App\Imports\CustomerImport; use Illuminate\Contracts\Validation\Rule; use Maatwebsite\Excel\Facades\Excel; class CsvUnique implements Rule { public function __construct($column) { $this->column = $column; } public function passes($attribute, $value) { $data = Excel::toArray(new CustomerImport(), $value); $names = array_map(function($i) { return $i[0]; }, array_slice($data[0],1)); return count($names) === count(array_unique($names)); } public function message() { return 'The :attribute has already been taken.'; } }Luego puede usarlo dentro de su lógica de validación de esta manera:
$request->validate( ['file' => ['required', 'file', 'mimes:txt,csv', new CsvUnique('name')]], ['file.required' => 'Please upload the file'] ); Tenga en cuenta que pasamos el nombre de la columna, en este name canse a la regla personalizada.