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

Mithridates's avatar

how do I query this relation with eloquent

I'm using Laravel and eloquent obviously. I have 4 models and tables.

1 => city 
2 => location
3 => venue 
4 => tag

now bear with me to describe relationship. a city has many locations and a location belongs to a city. a location belongs to a venue and a venue has one location. a venue belongs to many tags and a tag belongs to many venue (Many to many relationship)

Here are the query I wanna executed. given A city, how can I filter venues of that city based on tags. example: for city Austin I wanna get venues that have tag "special".

and Also, how many queries are executed for perform this task.Is it efficient to perform this kind of task with this database model.

I tried to be as explicit as possible but if some parts seems vague for you, please don't hesitate to ask. thanks

0 likes
7 replies
JarekTkaczyk's avatar
Level 53

@Mithridates

Your relations should be:

City hasMany Location
Location hasOne Venue (or hasMany maybe?)
City hasManyThrough Venue, Location

then as simple as this:

$city = City::where('name', 'Austin')->firstOrFail();

// having one tag, assuming tags.name is the field for lookup
$tag = 'special';
$city->venues()->whereHas('tags', function ($q) use ($tag) {
    $q->where('name', $tag);
})->get();

// having any of these tags
$tags = ['special', 'not-that-special'];
$city->venues()->whereHas('tags', function ($q) use ($tags) {
    $q->whereIn('name', $tags);
})->get();

// having all of these tags, assuming there are no duplicates venue-tag in pivot table
$tags = ['special', 'not-that-special'];
$city->venues()->whereHas('tags', function ($q) use ($tags) {
    $q->whereIn('name', $tags);
}, '=', count($tags))->get();
Mithridates's avatar

@JarekTkaczyk thanks a lot. I know the term efficient is somehow a vague term.
But do you think this query is a efficient query to be executed repeatedly?

JarekTkaczyk's avatar

@Mithridates First and foremost cache to the rescue!

And I wouldn't worry about this query untill you know for sure that it is a bottleneck of your app - as always.

Please or to participate in this conversation.