Henri Karhunen
Henri Karhunen

Reputation: 33

Laravel 5.6.8 Eloquent and many to many + many to one joins

I have many to many connect with between user - cityarea. I have also area which connect cityarea (One cityarea can connect only one area).

I have this database structure:

users

cityareas

cityarea_user

areas

Next I have Models

User

public function cityareas()
{
    return $this->belongsToMany('App\Cityarea');
}

Cityarea

public function area()
{
    return $this->belongsTo('App\Area');
}

public function users()
{
    return $this->belongsToMany('\App\User');
}

Area

public function cityareas()
{
    return $this->hasMany('App\Cityarea');
}

QUESTION:

How I can get all users where areas.name = "South" with Eloquent ?

Thanks!!

Upvotes: 2

Views: 309

Answers (3)

Faraz Irfan
Faraz Irfan

Reputation: 1326

Jeune Guerrier solution is perfect, but you can use with() method of eloquent If you also need cityarea collection along with users collection.

$users = User::with('cityareas')->whereHas('cityareas.area', function ($query) {
    $query->where('name', 'South');
})->get();

Upvotes: 0

Chibueze Opata
Chibueze Opata

Reputation: 10054

This is exactly what the belongs to many relationships is built for.

You simply have to do, Cityarea::where('name', 'South')->first()->users;

If you want to do something further with the query, e.g. sort by users created at, you can do

Cityarea::where('name', 'South')->first()->users()->orderBy('creaated_at', desc')->get();

Note that if there is no such Cityarea with name 'South', the ->first() query above will return null and therefore will fail to fetch the users.

A more performant way to do it programmatically is to use the whereHas approach as discussed in the comments below.

Upvotes: -1

Prince Lionel N'zi
Prince Lionel N'zi

Reputation: 2588

By using whereHas, you can do:

$users = User::whereHas('cityareas.area', function ($query) {
    $query->where('name', 'South');
})->get();

Upvotes: 2

Related Questions