Действия Laravel Nova относятся к нерабочему полю

#laravel #laravel-nova

#laravel #laravel-nova

Вопрос:

У меня есть это простое действие:

 /**
 * Perform the action on the given models.
 *
 * @param  LaravelNovaFieldsActionFields  $fields
 * @param  IlluminateSupportCollection  $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),
    ];
}
 

Сначала это кажется нормальным, но когда я выбираю пользователя из отношения belongsTo и пытаюсь сохранить, возникает исключение:

 Argument 1 passed to LaravelNovaFieldsBelongsTo::getRelationForeignKeyName() must be an instance of IlluminateDatabaseEloquentRelationsRelation, instance of IlluminateSupportFluent given, called in /Users/rd/Sites/bns-crm/vendor/laravel/nova/src/Fields/BelongsTo.php on line 212
 

Ответ №1:

Да, я знаю, что я опаздываю, но — вот решение для этого: используйте поле выбора вместо belongsTo и выберите свои варианты для построения пар ключ-значение:

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

Затем в дескрипторе вы должны указать идентификаторы в $fields:

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

Ответ №2:

Проверьте свои пространства имен. Вы импортировали правильный класс? Класс пользователя должен быть классом ресурсов

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

Комментарии:

1. Да, все в порядке. Проблема в том, что вы просто не можете этого сделать, используйте отношения в полях действий.

2. Эй, вы нашли решение этой проблемы?

3. @RomkaLTU У вас есть какие-нибудь рекомендации по этому поводу?

Ответ №3:

Возможно, я опоздал, но для таких, как я, желающих использовать поле belongsTo с возможностью поиска, потому что модель, в которой они хотят выполнить поиск, содержит слишком много записей, чтобы поместить их в обычное поле выбора, вот решение, которое я нашел:

Создайте класс в App Nova Fields с помощью этого кода:

 <?php

namespace AppNovaFields;

use LaravelNovaFieldsBelongsTo;
use LaravelNovaHttpRequestsNovaRequest;

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;
        }
    }
}
 

Затем используйте его так, как вы бы использовали обычное поле belongsTo. Просто не забудьте заполнить 3 аргумента в make, так, например:

 BelongsToForActions::make('User', 'relation', AppNovaUser::class)->searchable()
 

Помните, что «отношение» должно существовать.

Ответ №4:

Я фактически исправил это, высмеяв пару ключ-значение, используемую в этом отношении.

Сначала я создаю массив со столбцом ID в качестве ключа и столбцом name в качестве значения.

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

Затем я использую поле Select nova для его отображения.

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