Bervetuna's avatar

hasManyThrough relation in combination with ManyToMany?

I have 3 models:

  • User
  • Bankcard
  • Department

There is a many to many relationship defined between the User model and the Department model (a user can belong to many departments, a department has many users).

There is a one to many relationship between Bankcard and Department (a bankcard belongs to a department, a department can have many bankcards).

I would like to define a bankcard function in de user model to return the bankcards that belong to the departments that are related to the user.

My first thought was to work with a hasManyThrough relation, but that seems to be restricted to models that have a one to one relationship?

How could I define this bankcard relationship in the user model.

I tried with this (my table names are in Dutch, sorry. Department is 'afdeling'):

public function bankkaarten()
    {
        return Bankkaart::select('bankkaarts.*')
            ->join('afdelings', 'bankkaarts.afdeling_id', '=', 'afdelings.id')
            ->join('afdeling_user', 'afdelings.id', '=', 'afdeling_user.afdeling_id')
            ->where('afdeling_user.user_id', $this->id)
            ->get();
    }

But that results in an error: App\Models\User::bankkaarten must return a relationship instance.

0 likes
1 reply
LaryAI's avatar
Level 58

To define a relationship between the User model and the Bankcard model, you can use a hasManyThrough relationship in combination with the many-to-many relationship between the User and Department models. Here's how you can define the relationship in the User model:

public function bankcards()
{
    return $this->hasManyThrough(Bankcard::class, Department::class, 'id', 'department_id')
        ->withTimestamps();
}

This relationship will return all the bankcards that belong to the departments that are related to the user. The hasManyThrough method takes four arguments:

  1. The related model (Bankcard::class)
  2. The intermediate model (Department::class)
  3. The foreign key of the intermediate model (id)
  4. The foreign key of the related model (department_id)

The withTimestamps method is used to include the timestamps in the pivot table.

You can then access the bankcards of a user like this:

$user = User::find(1);
$bankcards = $user->bankcards;

This will return a collection of Bankcard models.

Note that you need to make sure that the Department model has a belongsToMany relationship with the User model and a hasMany relationship with the Bankcard model. Here's how you can define these relationships in the Department model:

public function users()
{
    return $this->belongsToMany(User::class);
}

public function bankcards()
{
    return $this->hasMany(Bankcard::class);
}

Please or to participate in this conversation.