Skip to content

Using Select within BelongsToMany fields() #6512

@Norgul

Description

@Norgul
  • Laravel Version: v11.15.0
  • Nova Version: v4.34.3
  • PHP Version: 8.2.20
  • Database Driver & Version:
  • Operating System and Version: MacOS Sonoma 14.5 (23F79)
  • Browser type and version: Chrome Version 127.0.6533.90 (Official Build) (arm64)

Description:

Not sure if this is a bug or I implemented something wrong. I have a pivot table with additional FK (unit_id). If I use Select in fields() method pointing to that additional FK, saving the relation will fail even though unit_id is present in the payload in the failing request.

// migration
Schema::create('recipe_composition', function (Blueprint $table) {
    $table->id();
    $table->foreignId('parent_id')->constrained('products');
    $table->foreignId('child_id')->constrained('products');

    $table->foreignId('unit_id')->constrained();
    ...
});

// Product.php
public function children(): BelongsToMany
{
    return $this->belongsToMany(self::class, 'recipe_composition', 'parent_id', 'child_id')
        ->withPivot(RecipeComposition::WITH_PIVOT)
        ->using(RecipeComposition::class)
        ->with('children')
        ->withTimestamps();
}

// RecipeComposition.php pivot model
class RecipeComposition extends Pivot
{
    public const WITH_PIVOT = [
        'unit_id',
        'net_amount',
        'gross_amount',
        'note',
        'removable_on_sale',
    ];

    public function parent(): BelongsTo
    {
        return $this->belongsTo(Product::class, 'parent_id');
    }

    public function child(): BelongsTo
    {
        return $this->belongsTo(Product::class, 'child_id');
    }

    public function unit(): BelongsTo
    {
        return $this->belongsTo(Unit::class);
    }
}

// Nova relation
BelongsToMany::make('Recipe elements', 'children', Product::class)
    ->fields(fn() => [
        Select::make('Unit', 'unit_id')
            ->dependsOn('children', function (Select $field, NovaRequest $request, FormData $formData) {
                $productId = $formData->get('children');

                /** @var \App\Models\Tenant\Product $product */
                $product = \App\Models\Tenant\Product::query()->with('unit')->find($productId);

                if (!$product) {
                    $field->readonly();
                    return;
                }

                $field->options(fn() => collect()
                    ->merge(Collection::wrap($product->unit->ancestors))
                    ->merge(Collection::wrap($product->unit))
                    ->merge(Collection::wrap($product->unit->grandchildren))
                    ->pluck('label', 'id')
                );

                $field->value = $product->unit->id;
            }),
        ...
    ])
    ->singularLabel('Recipe or Goods'),

image

If however I replace Select with a hardcoded Text or Number field, it will have the same payload, but will go through.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions