laravel-nova-csv-import icon indicating copy to clipboard operation
laravel-nova-csv-import copied to clipboard

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

Open phpMagpie opened this issue 1 year ago • 6 comments
trafficstars

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 avatar Apr 28 '24 14:04 phpMagpie

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 avatar Apr 28 '24 15:04 phpMagpie

@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).

phpMagpie avatar Jun 22 '24 08:06 phpMagpie

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

stevenwaskey avatar Sep 24 '24 01:09 stevenwaskey

@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.

phpMagpie avatar Sep 24 '24 07:09 phpMagpie

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

simonhamp avatar Sep 24 '24 14:09 simonhamp

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

phpMagpie avatar Sep 25 '24 07:09 phpMagpie