Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three-way many-to-many relationship in Laravel

I have three models that need to be related in a pivot table: User, Student, Plan. So each user can subscribe a student to a plan.

What I've found so far is to create a pivot for two of the models, say User and Plan, and attach the student_id as an extra field:

$user->plans()->attach([1 => ['student_id' => $student_id]);

One problem with this is that if I try to retrieve the plans for a particular user, I don't get the student model, just the id, so:

return $this->BelongsToMany('App\Plan', 'plans_students_users', 'user_id', 'plan_id')
->withPivot('student_id');

So, I'd have to do a second query to get the student model.

Is there any other way to go about it, given that I'll want to make queries in all directions, e.g:

$user->plans() (attaching the students)
$student->plans() (attaching the user)
$plan->users() (attaching the students)
$plan->students() (attaching the users)
like image 798
babbaggeii Avatar asked Jun 04 '15 16:06

babbaggeii


People also ask

What are some examples of a many-to-many relationship?

A typical example of a many-to many relationship is one between students and classes. A student can register for many classes, and a class can include many students. The following example includes a Students table, which contains a record for each student, and a Classes table, which contains a record for each class.

How do you connect many-to-many relationships?

For those relationships, you simply connect the appropriate fields with a line. To create many-to-many relationships, you need to create a new table to connect the other two. This new table is called an intermediate table (or sometimes a linking or junction table).

How many types of relationships are there in Laravel?

One To One (Polymorphic) One To Many (Polymorphic) Many To Many (Polymorphic)


1 Answers

I often use another model to abstract a three-way many to many relations.

We have our relation I will call the relation relation.

The db structure:

table relations: id, user_id, student_id, plan_id

The app has the following four models:

  • User
  • Student
  • Plan
  • Relation

Here is how we connect the four models using Relationships:

User, Plan, Student:

function relations() {
   return $this->hasMany(Relation::class);
}

Relation:

function student() {
   return $this->belongsToMany(Student::class);
}

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

function plan() {
   return $this->belongsToMany(Plan::class);
}

You can retrieve the entities like this:

//get the plan of a student related to the user
$user->relations()->where('student_id', $student)->first()->plan();

//get all entities from the relation
foreach ($user->relations as $relation) {
    $plan = $relation->plan;
    $student = $relation->student;
}

Its the only solution I have found in all the time I have been developing on Laravel.

like image 78
Carlos Herrera Plata Avatar answered Sep 21 '22 16:09

Carlos Herrera Plata