orlyapps / nova-belongsto-depend

Larave Nova BelongsTo Field with Dependcy
MIT License
182 stars 65 forks source link

Writes Wrong Value On Save #56

Open Aontaigh opened 4 years ago

Aontaigh commented 4 years ago

I have the following 'task' model that belongsTo a 'template' via:

public function template() {
    return $this->belongsTo(Template::class, 'template_id', 'tnt_id');
}

This is then the code in my 'task' in Nova:

NovaDependencyContainer::make([
    NovaBelongsToDepend::make('Product', 'product', '\App\Nova\CustomProductImage')
    ->options(\App\CustomProductImage::all())->nullable(),

    NovaBelongsToDepend::make('Template', 'template', 'App\Nova\Template')
        ->optionsResolve(function ($item) {
            return $item->templates()->get(['id', 'name']);
        })->dependsOn('Product')
    ->hideFromIndex()
    ->nullable(),
])->dependsOn('attachments_option', 3)

Instead of inserting the 'tnt_id' value as specified in the relation in the model, it is inserting the id.

I could do something along the lines of using an observer to solve this issue once the value is stored though that would obviously be inefficient and would prefer a more elegant solution.

albertpratomo commented 2 years ago

This is because NovaBelongsToDepend@fillAttributeFromRequest method doesn't use Eloquent Model's fill method.

/**
     * Fills the attributes of the model within the container if the dependencies for the container are satisfied.
     *
     * @param NovaRequest $request
     * @param string $requestAttribute
     * @param object $model
     * @param string $attribute
     */
    protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute)
    {
        if ($request->exists($requestAttribute)) {
            $model->{$attribute} = $request[$requestAttribute];
        }

        if ($this->fallback) {
            $this->fallback->fill($request, $model);
        }
    }

If you overwrite this method to be this, it should work fine:

/**
     * {@inheritdoc}
     */
    protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute)
    {
        // Override NovaBelongsToDepend's implementation which is buggy.
        // Use `fill` method to ensure that only fillable attribute is filled.
        if ($request->exists($requestAttribute)) {
            $model->fill([
                $attribute => $request[$requestAttribute],
            ]);
        }

        if ($this->fallback) {
            $this->fallback->fill($request, $model);
        }
    }