Search code examples
laravelhas-and-belongs-to-manylaravel-nova

Laravel Nova field BelongsToMany drilling down the data


I am developing a Web Application using Laravel. I am using Laravel Nova for building the admin panel. But I am having an issue with BelongsToMany field.

I have the database schema as follow

Area

Station - has area_id because an area has many stations

manager - area_id because each user belongs to an area

Area_station - station_id and manager_id (many to many)

So in the Station nova resource, I added a field like this.

BelongsToMany::make('Managers', 'managers', Manager::class),

Therefore, when I go to the Station details page from the Nova admin panel and select "Attach manager", in the dropdown of the next page (page to attach a manager to the department), I can see all the available managers in the database.

But instead of displaying all the available managers in the drop down, I like to filter the managers/users which belongs to the same area as the selected Station. I mean when I attached a manager to the Station, I have to select a station. Is it possible to filter or to achieve what I want in Nova?


Solution

  • Override relatableQuery function which will determines which instances of the model may be attached to other resources, under Manager nova resource.

    Approach 1

    public static function relatableQuery(NovaRequest $request, $query)
    {
        // In case manager is get attached to another resource except Station. 
        if ($request->resource() == 'App\Nova\Station') { 
            $station = $request->findResourceOrFail();
            return $query->where('area_id', $station->area_id);
        }
    
        return parent::relatableQuery($request, $query);
    }
    

    Update

    Approach 2 - Learned something new just now.

    You can add a relatable query for the relationship under Station Nova resource. In this case no need to check for the resource.

    public static function relatableManagers(NovaRequest $request, $query)
    {
        $station = $request->findResourceOrFail();
        return $query->where('area_id', $station->area_id);
    }
    

    Approach 2 is better in my opinion.