tuesdave's avatar

Nova 4 - dependsOn on a BelongsTo relationship

I'm trying to use the dependsOn method on a BelongsTo field relationship.

The documentation shows a simple implementation using a Text field https://nova.laravel.com/docs/4.0/resources/fields.html#dependent-fields

In the code below, I am trying to load only Licenses that the user owns, based on the User that is selected when creating a new Order resource. User hasMany Licenses relationship exists.

Nova/Order.php

BelongsTo::make('User'),
BelongsTo::make('License')
         ->dependsOn(['user'], function(BelongsTo $LicenseSelect, NovaRequest $request, FormData $formData) {
                    // need to set the options for this BelongsTo relationship dropdown to show only Licenses that the selected User owns
         }),

Models/User.php

public function licenses()
{
    return $this->hasMany(License::class);
}

Models/License.php

public function user()
{
    return $this->belongsTo(User::class);
}
0 likes
9 replies
Nesster's avatar

@tuesdave Did you figure it out ? Also looking into this at the moment. I've seen some techniques using a Select on the form and a BelongsTo on the index page, but I want to make use of the showCreateRelationButton() on the form, so I probably can't go the Select route. Thanks for any input you might have on this.

tuesdave's avatar

@Nesster No solutions yet. You would think this would be a common use case within admin workflows!

jigar_dhulla's avatar

What I have done is that while Creating and Updating a Resource, I did not use BelongsTo but used Select field instead with depends on (which has options method).

Something like this:

BelongsTo::make('User'),
BelongsTo::make('License')->exceptOnForms(),
Select::make('License', 'license_id')
    ->dependsOn('user', function (Select $field, NovaRequest $request, FormData $formData) {
        $user = UserModel::whereId($formData->user ?? $this->user_id)->first();
        $field->options($user?->licenses->pluck('name', 'id'));
    })->onlyOnForms(),
Nesster's avatar

@jigarakatidus If you use the select on the form, you can't make use of the showCreateRelationButton() though, so depends on your needs, not always a viable solution.

devenjahnke's avatar

@jigarakatidus @nesster @vitorbarroso You can grab the ID of the model the fields are dependent on from the request query parameters when creating an object via the showCreateRelationButton view.

public function fields(Request $request): array
{
 return [
  BelongsTo::make('Event', 'event', Event::class),

  Select::make('Location', 'location_id')
    ->onlyOnForms()
    ->dependsOn('event', function (Select $field, NovaRequest $request, FormData $formData) {
      if ($formData->get('event') || $this->event_id) {
        $event = \Domain\Event\Models\Event::where('id', $formData->event ?? $this->event_id)->first();
      }
      else {
       $event = \Domain\Event\Models\Event::firstWhere('id', $request->query('viaResourceId'));
      }
      $field->options($event?->venue->locations()->pluck('name', 'id'));
     }),
    ];
}
1 like
seyam's avatar

BelongsTo::make('City')->required(),
BelongsTo::make('Neighborhood')
    ->dependsOn(['city'], function (BelongsTo $field, NovaRequest $request, FormData $formData) {
        $field->relatableQueryUsing(function (NovaRequest $request, Builder $query) use ($formData) {
            $query->when($formData->city, function ($query) use ($formData) {
                $query->where('city_id', $formData->city);
            });
        });
    }),

you can remove when to only show options if the city is selected.

6 likes
riseabove2_2's avatar

@seyam Amazing! Thank you! Where in the world did you find this as an option? Was this even remotely hinted at in the nova docs?

Please or to participate in this conversation.