Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

philipbaginski's avatar

Filtering BelongsTo relation.

Hi Everybody!

New, old problem. How to filter BelongsTo relation? I have relation:

public function mom()
    {
        return $this->belongsTo(Human::class);
    }

When trying to choose mom it shows me tousands records, does not matter of sex.

I want to see only records from 'humans' table with 'sex_id' = 1

I reached the end of Internet and back, I could not fine any working solution.

Any help?

0 likes
9 replies
franzdumfart's avatar

I'm not 100% sure, but why not add the where condition next to the belongsTo?

return $this->belongsTo(Human::class)->whereSexId(1);
philipbaginski's avatar
public function mom()
    {
        return $this->belongsTo(Human::class)->where('sex_id', '=', 1);
    }

does not work at all. I tried ->whereSexId(1); - the same. Filtering does not work.

CorvS's avatar

@philipbaginski

When trying to choose mom it shows me tousands records, does not matter of sex.

What do you mean by that? The relationship should return one model instance only, not thousand of records (i.e. a collection), so filtering a single entry doesn't make sense in the first place.

philipbaginski's avatar

I mean: I have a table 'humans'. When creating new model, I have to choose mom and dad. Mom and dad are coming from the same table - 'humans', but they have different sex. So, in field mom - belongs to Human::class I would like to have humans ONLY with sex = 1(woman), and in field dad I would like to have humans with sex = 2 (man).

CorvS's avatar

@philipbaginski If I understand you correctly you want to select the mom and dad when creating a new user? Then you probably want all women and men to select the mom/dad from:

$women = Human::where('sex_id', 1)->get();
$men = Human::where('sex_id', 2)->get();
philipbaginski's avatar

Okay. I have found part of the solution.

In Resource.php relatableQuery needs to be modifed:

    public static function relatableQuery(NovaRequest $request, $query)
    {
        // Create the filter method name
        $method = 'relatable' . Str::plural(class_basename(get_called_class())) . 'Filter';

        // Get the called resource instance
        $resource = $request->newResource();

        // Check if the filter method exists
        if (method_exists($resource, $method)) {
            $query = $resource->{$method}($request, $query);
        }

        return parent::relatableQuery($request, $query);
    }

And this is a sample of relatableQuery placed in resource file:

    public function relatableUsersFilter(NovaRequest $request, $query)
    {
        $query->whereHas('teams', function ($query) {
            $query->where('team_id', $this->team_id);
        });

        return $query;
    }

Can anyone help me to modify it with my case?

philipbaginski's avatar

I ended up with this working solution. If anyone knows bettet/easier, feel free to share.

    public static function relatableQuery(NovaRequest $request, $query)
    {
        $requestSegment = strtolower($request->segment(4));
        // Restrict humans to women and ancestors.
        if ($requestSegment === 'mom')
        {
            return $query->where('sex_id', 1)->where('ancestor', 1);
        }
        else {
            return $query;
        }
    }
philipbaginski's avatar

I don't know if this is a proper option regarding speed and amount of queries, but I found one option more to filter BelongsTo field:

Select::make('Mom', 'mom_id')
                ->options(\App\Models\Human::where('sex_id', 1)
                ->pluck('name', 'id'))
				->searchable()

Please or to participate in this conversation.