Relationship for Siblings are many to many self relationship. So, for many to many self relationship, we can define two functions in the model:
public function siblings()
{
return $this->belongsToMany('Student', 'student_sibling', 'student_id', 'sibling_id');
}
public function siblingOf()
{
return $this->belongsToMany('Student', 'student_sibling', 'sibling_id', 'student_id');
}
The first one returns the students who are siblings of the student. The reverse is also true for siblings. So, the second one returns the students of whom the student is a sibling.
So, we can merge both the collections to get a list of students who are siblings of the student. Here is my code in the controller method:
$siblingOf = $student->siblingOf;
$siblings = $student->siblings;
$siblings = $siblings->merge($siblingOf);
But there is more. Siblings relationship is a chain relationship unlike friends relationship. This mean, if X is a sibling of Y and Y is a sibling of Z, then Z is a sibling of X.
So, how to get the collection of all students who are sibling of a student?
I'm assuming that you have a Student model, with student_id as your primary key, and a pivot table that looks something like this:
In this example, we want to be able to discern that 1, 2, 3 and 4 are all siblings of each other. 5 and 6 are siblings as well.
One way to solve this is by gathering the result of the two
belongsToMany()
relationships in your model—as you did in your question—and then recursively iterating over the result, continuing to check thebelongsToMany()
functions until we run out of siblings.In the Student model, define two functions:
In your controller, find the initial student, and then call
getAllSiblings()
from Student:The result is a collection with all the siblings of the original student. So, if you run this for student 1, you will get a collection containing students 2, 3 and 4. (If you'd prefer to keep the original student as part of the siblings collection, so that running this for 1 returns 1, 2, 3 and 4, simply remove the
optional
step ingetAllSiblings()
.)From there, you can cast the collection to an array, or sort, etc. as needed.
Recursive relation could do this, BUT it will probably cause infinite loop (function nesting limit error).
Anyway this is how to setup such relation:
Then you call, as simple as this: