Michał Lipa
Michał Lipa

Reputation: 978

Laravel Check if Users have this same relation

I would like to check if two users have these same relation. I have models: User and Team.

User relations:

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

Team relation:

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

So users can be part of few teams. How to check if 2 specified users have common team?

Upvotes: 1

Views: 1125

Answers (3)

Norgul
Norgul

Reputation: 4783

What about checking by name in nested loop like so:

$user1 = User::find(1);
$user2 = User::find(2);

foreach($user1->teams->name as $team1)
   foreach($user2->teams->name as $team2)
        if($team1 == $team2)
        //do awesome stuff

The above won't work. The correct code is (as suggested by Filip Koblański):

$user1 = User::find(1);
$user2 = User::find(2);

foreach($user1->teams as $team1)
   foreach($user2->teams as $team2)
        if($team1->name == $team2->name)
        //do awesome stuff

Upvotes: 0

Matt McDonald
Matt McDonald

Reputation: 5050

Presuming you're looking at your models as Eloquent Collections, there are several methods available to you that should achieve this.

One option would be intersect (more here: https://laravel.com/docs/5.2/collections#method-intersect)

$user = User::with('teams') -> find($id); 
$userCompare = User::with('teams') -> find($idCompare);

dump( $user -> teams -> intersect($userCompare -> teams) -> count() );

Upvotes: 1

PeterTheLobster
PeterTheLobster

Reputation: 1395

I cannot help you with eloquent, but I can help you with a raw query. Considering your tables are called users and team_memberships (your many-to-many table storing the memberships) you can do a raw query like this.

function checkCommonTeams($user_id_A, $user_id_B){
 $common = DB::select(
  DB::raw(
   'SELECT users.*,teams.* FROM users as user_A
    INNER JOIN team_memberships as teams ON user_A.id = teams.member_id
    INNER JOIN team_memberships as teams_B ON teams_B.id = teams.id
    WHERE teams_B.member_id = :user_B AND users.id = :user_A LIMIT 1'
  ),
  ['user_A' => $user_id_A, 'user_B' => $user_id_B] 
 );
 return (!count($common)) ? false : true;
}

Something like this should work and perform way FASTER than querying teams of both users and checking against each value etc. You just have to check for yourself how your DB is structured.

This will return true or false if they share teams.

My philosophy is that if you can do something like this in your DB, then try to do it, because it should almost always be able to do it better than multi-querying and comparing the values in php.

Upvotes: 0

Related Questions