0

I am using the Laravel Excel package to handle bulk uploads. Whilst Im able to get the data to upload successfully, my web console indicates and error that 'staff_id' doesn't have a default value. I have tried to catch this as an exception but this does not get triggered. I am using the ToModel import as indicated below

class EmployeesImport implements ToModel, WithHeadingRow
{
    public function model(array $row)
    {
        try {
            return new Employee([
                'staff_id' => $row['staff_id'],
                'first_name' => $row['first_name'],
                'middle_name' => $row['middle_name'],
                'last_name' => $row['last_name'],
                'national_id' => (string) $row['national_id'],
                'department_id' => 1,
            ]);
        } catch (\Exception $e) {
            dd($e->getMessage(), $row);
        }
    }
}

The CSV Im importing has the following structure

Excel that Im importing with input name ('bulk')

Within my controller, I have this to exceute the upload/import

Excel::import(new EmployeesImport(), request()->file('bulk'));

And finally, this is my Employees Model, showing the fillable fields

class Employee extends Model
{
    use SoftDeletes;

    protected $table = "employees";

    protected $fillable = [
        "staff_id", "first_name", "middle_name", "last_name", "national_id", "department_id", "avatar"
    ];
}

(One last thing) In case it may hold relevance - my migration file's up method

public function up()
{
    Schema::create('employees', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('staff_id')->unique();
        $table->string('first_name');
        $table->string('middle_name')->nullable();
        $table->string('last_name');
        $table->string('national_id')->unique();
        $table->unsignedBigInteger('department_id');
        $table->longText('avatar')->nullable();
        $table->timestamps();
        $table->softDeletes();

        //Foreign keys
        $table->foreign('department_id')->references('id')->on('departments')->onDelete('cascade');
    });
}
Francis Kisiara
  • 125
  • 2
  • 14
  • on the documentation I saw Excel::import(new UsersImport, 'users.xlsx'); and in your code I see you are using as new UsersImport() as function, is there any difference in using one or the other – Aatish Sai Mar 21 '19 at 09:05
  • That shouldn't be a problem, both syntax should work the same way in this case – Francis Kisiara Mar 21 '19 at 10:23

2 Answers2

0

According to the documentation you can catch the errors at the end

https://docs.laravel-excel.com/3.1/imports/validation.html#gathering-all-failures-at-the-end

Gathering all failures at the end

You can gather all validation failures at the end of the import, when used in conjunction with Batch Inserts. You can try-catch the ValidationException. On this exception you can get all failures.

Each failure is an instance of Maatwebsite\Excel\Validators\Failure. The Failure holds information about which row, which column and what the validation errors are for that cell.

try {
    // import code
} catch (\Maatwebsite\Excel\Validators\ValidationException $e) {
     $failures = $e->failures();

     foreach ($failures as $failure) {
         $failure->row(); // row that went wrong
         $failure->attribute(); // either heading key (if using heading row concern) or column index
         $failure->errors(); // Actual error messages from Laravel validator
         $failure->values(); // The values of the row that has failed.
     }
}
Christophvh
  • 12,586
  • 7
  • 48
  • 70
0

you make your models like that:

protected $fillable = [
        "staff_id", "first_name", "middle_name", "last_name", "national_id", "department_id", "avatar"
    ];

and your row like this:

return new Employee([
                'staff_id' => $row['staff_id'],
                'first_name' => $row['first_name'],
                'middle_name' => $row['middle_name'],
                'last_name' => $row['last_name'],
                'national_id' => (string) $row['national_id'],
                'department_id' => 1,

just matching the $row and $fillable, i mean in your $row the "avatar" must have a value to fill the $fillable, or you can erase the "avatar" from you fillable