simonhamp / laravel-nova-csv-import

The best CSV import component for Laravel Nova
https://novapackages.com/packages/simonhamp/laravel-nova-csv-import
MIT License
168 stars 76 forks source link

Nova BelongsTo field->attribute returning relation name rather than foreign_key #82

Open phpMagpie opened 6 months ago

phpMagpie commented 6 months ago

I'm trying to import records into a link model similar to

- id
- class_id
- student_id
- some_other_fields

My Nova Resource has fields of

ID::make()->sortable(),
BelongsTo::make('Class'),
BelongsTo::make('Student'),
...,

The import process looks great all the way up to the import then returns an error with class_id { "errorInfo": [ "HY000", 1364, "Field 'class_id' doesn't have a default value" ], "connectionName": "mysql" }

I think this is caused by the BelongsTo Class field being mapped to the class relation name rather than the class_id model field.

On the Configure screen the fields are showing as

- Class (class)
- Student (student)

rather than

- Class (class_id)
- Student (student_id)

As such the import is failing as the model needs values for class_id and student_id

If this is the case, I'm not sure how to solve/work around this. Hopefully I'm missing something obvious.

UPDATE:

If I change my resource fields to ...

ID::make()->sortable(),
BelongsTo::make('Class'),
Number::make('Class', 'class_id'),
BelongsTo::make('Student'),
Number::make('Student', 'student_id'),
...

I can then get the import to work, which seems to prove my theory, but is not a useable workaround as I don't want those number fields in my resource.

phpMagpie commented 6 months ago

I've done some more digging and, unless I've missed something obvious in my configuration, then the issue appears to be in getAvailableFieldsForImport() https://github.com/simonhamp/laravel-nova-csv-import/blob/main/src/Http/Controllers/ImportController.php#L221

A hacky soluion which gets things working is

protected function getAvailableFieldsForImport(string $resource, ImportNovaRequest $request): array
{
    ...

    $fields = $fieldsCollection->map(function (Field $field) use ($novaResource, $request) {
        $request->setImportResource($novaResource);

        return [
            'name' => $field->name,
            'attribute' => $field->component === 'belongs-to-field'
                ? $field->attribute . '_id'
                : $field->attribute,
            'rules' => $this->extractValidationRules($novaResource, $request)->get($field->attribute),
        ];
    });

    ...
}

Not sure how we can use any of the properties from the $field object to get the foreign_key from the BelongsTo relation when we don't have a model instance to work with at this point.

phpMagpie commented 4 months ago

@simonhamp Sorry to tag you into this directly, but would appreciate knowing if this package handles relationships (and if so what I'm doing wrong in my configuration).

stevenwaskey commented 1 month ago

@phpMagpie I'm seeing the same symptoms. Were you able to derive a solution aside from modifying the package?

phpMagpie commented 1 month ago

@stevenwaskey I've not put this package into production, so did not get any further than the above I'm afraid. I hope you have better luck.

Shame @simonhamp does not have the time to support it, but understandable as I'm sure he has a day job to tend to.

simonhamp commented 1 month ago

The package doesn't support relationships yet. If someone wants to PR support for it, I'll be happy to review it

phpMagpie commented 1 month ago

@simonhamp thanks for the update and sharing the package in the first place.