RomkaLTU
RomkaLTU

Reputation: 4128

Laravel Nova Actions BelongsTo field not working

I have this simple action:

/**
 * Perform the action on the given models.
 *
 * @param  \Laravel\Nova\Fields\ActionFields  $fields
 * @param  \Illuminate\Support\Collection  $models
 * @return mixed
 */
public function handle(ActionFields $fields, Collection $models)
{
    foreach ($models as $model) {
        $model->update([
            'user_id' => $fields->user
        ]);
    }
}

/**
 * Get the fields available on the action.
 *
 * @return array
 */
public function fields()
{
    return [
        BelongsTo::make('User', 'user', User::class),
    ];
}

At first, it seems fine, but when I select User from BelongsTo relation and try to save exception is throwing:

Argument 1 passed to Laravel\Nova\Fields\BelongsTo::getRelationForeignKeyName() must be an instance of Illuminate\Database\Eloquent\Relations\Relation, instance of Illuminate\Support\Fluent given, called in /Users/rd/Sites/bns-crm/vendor/laravel/nova/src/Fields/BelongsTo.php on line 212

Upvotes: 0

Views: 4284

Answers (4)

Skato
Skato

Reputation: 31

Maybe I'm late, but, for the ones like me wanting to use the BelongsTo searchable field because the model they want to search in contains too much records to pack them in a normal Select field here is the solution I found:

Create a class in App\Nova\Fields with this code:

<?php

namespace App\Nova\Fields;

use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Http\Requests\NovaRequest;

class BelongsToForActions extends BelongsTo
{
    public function fillForAction(NovaRequest $request, $model)
    {
        $attribute = $this->attribute;

        if ($request->exists($attribute)) {
            $value = $request[ $attribute ];

            $model->{$attribute} = $this->isNullValue($value) ? null : $value;
        }
    }
}

Then use it like you would use a normal BelongsTo field. Just remember to fill the 3 arguments on the make, so, for example:

BelongsToForActions::make('User', 'relation', \App\Nova\User::class)->searchable()

Remember that 'relation' must exist.

Upvotes: 3

Dave
Dave

Reputation: 101

Yes i know i'm late but - here's a solution for this: Use a Select-Field instead of BelongsTo and Pluck your options to build Key-Value pairs:

public function fields()
{
    return [
        Select::make('debitor')->options(\App\Models\Debitor::pluck('Name', 'id'))
    ];
}

Then in the handle you should geht the ids in $fields:

public function handle(ActionFields $fields, Collection $models) {
    Log::info($fields);
}

Upvotes: 4

Niels Bosman
Niels Bosman

Reputation: 956

I actually fixed this by mocking the key value pair used in this relationship.

First I build an array with the ID column as key and the name column as value.

$clients = Client::all()
  ->keyBy('id')
  ->map(fn($client): string => $client['name'])
  ->toArray();

Then I use the Select nova field to display it.

Select::make('Klant', 'client')
  ->searchable()
  ->options($clients)
  ->rules('required'),

Upvotes: 1

keizah7
keizah7

Reputation: 743

Check your namespaces. Did you imported right class? User class must be resource class

public function fields()
{
    return [
        BelongsTo::make('User', 'user', User::class),
    ];
}

Upvotes: -1

Related Questions