dcasia / nova-inline-morph-to

A Laravel Nova field for displaying morphTo relationship inline.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Filling a relationship field fails if `fillAttributeFromRequest` returns a callback

stiknoltz opened this issue · comments

First off, thank you for all your work on this package. It's looking likely to play a central roll in the content management feature of a few projects.

I did run into a situation when an InlineMorphTo field includes a Resource that uses a field provided by Advanced Nova Media Library. It would appear that the situation could occur with any packaged field that returns anything but null from fillAttributeFromRequest.

To solve, I modified lines 253–257 of src/InlineMorphTo.php to

        foreach ($fields as $field) {
            $fill_value = $field->fill($request, $relatedInstance);

            if (is_callable($fill_value)) {
                call_user_func($fill_value);
            }
        }

This at least solves for situations where fillAttributeFromRequest returns a callback. I'm not sure if there are other possible scenarios that are missed since fillAttributeFromRequest can return mixed

If the above seems like a reasonable fix, I'm happy to provide a pull request.

Thanks!

Upon further testing, I realized that this only solves for instances where updating an existing inline relationship. It fails when creating a the relationship on a new model.

So, it really doesn't solve it at all. I'm investigating further.

@stiknoltz It`s a bit hard for me to do all the setup needed to reproduce this error right now, but can you try replacing the fill method with this and see if it works?:

I remember adding a return function from the fill method to the Advanced Media Library with this PR ebess/advanced-nova-media-library#61 , because that library needs to do some extra work after the model is saved to the database, I think regardless if the fill function bellow works or not on your case it would be best still to add it anyways so it keeps compatibility with packages that uses this "after save" mechanism, but give it a try perhaps this fixes your issue

public function fill(NovaRequest $request, $model)
{

    /**
     * @var Model $relatedInstance
     * @var Model $model
     * @var Resource $resource
     * @var Field $field
     */

    $resourceClass = $request->input($this->attribute);
    $relatedInstance = $model->{$this->attribute} ?? $resourceClass::newModel();
    $resource = new $resourceClass($relatedInstance);

    if ($relatedInstance->exists) {

        $resource->validateForUpdate($request);

    } else {

        $resource->validateForCreation($request);

    }

    $fields = $this->getFields($relatedInstance);
    $callbacks = [];

    foreach ($fields as $field) {

        $callbacks[] = $field->fill($request, $relatedInstance);

    }

    $relatedInstance->saveOrFail();

    $model->{$this->attribute}()->associate($relatedInstance);

    return function () use ($callbacks) {

        foreach ($callbacks as $callback) {

            if (is_callable($callback)) {

                call_user_func($callback);

            }

        }

    };

}

I have incorporated the changes above into version 0.1.9, hope it solves the issue with the adv image package