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

phayes0289's avatar

Filtering Records Based on A Value in a Relationship

In my Laravel project I have a "User" model that stores basic user info such as firstaname, lastname, email, empid, etc. I also have an "Assignment" model that extends information about the user. For example, it has the following fields:

user_id field, effective_dt, expiration_dt, station_id, division_id, rank_id title_id and additional similar fields.

The user_id field relates to the id in the “User” model. There is typically one or more records assigned to a user, but the current / active one is the one where the current date is greater than the effectivedt but less than the expiration_dt (if the expiration_dt is not null), otherwise less than or equal to the current datetime. The other records in the Assignment model that relate to the user are unused for this problem

I have a rrelationship built called “currentAssignment”. I use it to return the user data from the User model as well as current assignment data from the Assignment model. It looks like this:

public function currentAssignment()
    {
        return $this->hasOne(Assignment::class)
            ->where(function ($query) {
                $query->where('effective_dt', '<=', now())
                    ->where(function ($query) {
                        $query->where('expiration_dt', '>', now())
                            ->orWhereNull('expiration_dt');
                    });
            })
            ->orderBy('effective_dt', 'desc')
            ->orderBy('id', 'desc');
    }

Now I can easily display the users current assignment which includes their division, station and rank.

This works pretty well. But now I am in need of filtering the query list to include ONLY records where the station_id = a given value, such as tstation. This will reduce the query results from several hundred down to 20 or so.

For example, in CompanyopsController, I have a method called roster. Inside that method I have a simple eloquent query to get me all the users. I need to modify it so that is only gets me the users with a given station_id. In this case, I convert the station number to the id value and call it tstation:

public function roster($station, $shiftdate)
    {
        $stations = Station::where('status', 'published')->get();

        $tstation = Station::where('status', 'published')
        ->where('code', $station)
        ->first();

        if ($tstation) {
            $stationId = $tstation->id;

            $members = User::with(['currentAssignment.rank', 'currentAssignment.title', 'currentAssignment.station', 'currentAssignment.shift'])->get();

        } else {
            // Handle the case where no matching station is found based on the provided $station code.
        }
   
       return view('companyops.roster', compact('stations','members','station','shiftdate'));
    }

How do I add a filter to the $members query that will only return matches User and currentAssignment where thestation_id is equal to the value of tstatiion

0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

To filter the $members query to only include users with a currentAssignment where the station_id is equal to the value of $stationId, you can use the whereHas method. This method allows you to add query constraints to the relationships.

Here's how you can modify the $members query in your roster method:

public function roster($station, $shiftdate)
{
    $stations = Station::where('status', 'published')->get();

    $tstation = Station::where('status', 'published')
        ->where('code', $station)
        ->first();

    if ($tstation) {
        $stationId = $tstation->id;

        // Use whereHas to filter users based on the currentAssignment relationship
        $members = User::whereHas('currentAssignment', function ($query) use ($stationId) {
            $query->where('station_id', $stationId)
                ->where('effective_dt', '<=', now())
                ->where(function ($query) {
                    $query->where('expiration_dt', '>', now())
                        ->orWhereNull('expiration_dt');
                });
        })->with(['currentAssignment.rank', 'currentAssignment.title', 'currentAssignment.station', 'currentAssignment.shift'])->get();

    } else {
        // Handle the case where no matching station is found based on the provided $station code.
        $members = collect(); // Return an empty collection or handle as needed
    }

    return view('companyops.roster', compact('stations', 'members', 'station', 'shiftdate'));
}

In this solution, the whereHas method is used to apply additional constraints to the currentAssignment relationship. It ensures that only users with a currentAssignment that matches the station_id and the date conditions are retrieved.

The use keyword is used to pass the $stationId variable into the closure so that it can be used in the query condition.

Remember to handle the case where $tstation is null appropriately, as in the provided code, it will return an empty collection. You might want to redirect the user or display a message indicating that the station was not found.

Please or to participate in this conversation.