兄弟姐妹的Laravel口才关系 [英] Laravel Eloquent Relationships for Siblings

查看:85
本文介绍了兄弟姐妹的Laravel口才关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

兄弟姐妹之间的关系是多对多的自我关系.因此,对于多对多的自我关系,我们可以在模型中定义两个函数:

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);

但是还有更多.兄弟姐妹关系是一种链式关系,与朋友关系不同.这意味着,如果X是Y的同级,而Y是Z的同级,则Z是X的同级.

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?

推荐答案

我假设您有一个Student模型,其主键为Student_id,并且数据透视表如下所示:

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:

+---------+------------+------------+
| id (PK) | student_id | sibling_id |
+---------+------------+------------+
| 1       | 1          | 2          |
| 2       | 2          | 1          |
| 3       | 3          | 4          |
| 4       | 4          | 2          |
| 5       | 6          | 5          |
+---------+------------+------------+

在此示例中,我们希望能够辨别出1、2、3和4都是彼此的兄弟姐妹. 5和6也是兄弟姐妹.

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.

解决此问题的一种方法是,通过收集模型中两个belongsToMany()关系的结果(就像您在问题中所做的一样),然后递归遍历结果,继续检查belongsToMany()函数,直到我们运行没有兄弟姐妹.

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 the belongsToMany() functions until we run out of siblings.

在Student模型中,定义两个函数:

In the Student model, define two functions:

public function getAllSiblings(){

    // create a collection containing just the first student
    $this->siblings = $this->newCollection()->make($this);

    // add siblings (recursively) to the collection
    $this->gatherSiblings($this->student_id);

    // OPTIONAL: remove the first student, if desired
    $this->siblings->shift();

    return($this->siblings);
}

private function gatherSiblings($student_id){

    $checkStudent = Student::find($student_id);

    if ($checkStudent) {
        // get related siblings from model, combine them into one collection
        $siblingOf = $checkStudent->siblingOf()->get();
        $siblings = $checkStudent->siblings()->get();
        $siblings = $siblings->merge($siblingOf);

        // iterate over the related siblings
        $siblings->each(function($sibling)
        {
            // if we've found a new sibling who's 
            // not already in the collection, add it
            if(!$this->siblings->contains($sibling->student_id)) {
                $this->siblings->push($sibling);

                // look for more siblings (recurse)
                $this->gatherSiblings($sibling->student_id);
            };
        });
        return;
    }
}

在您的控制器中,找到最初的学生,然后从Student呼叫getAllSiblings():

In your controller, find the initial student, and then call getAllSiblings() from Student:

$student = Student::find($id);
$siblings = $student->getAllSiblings();

结果是一个包含原始学生所有兄弟姐妹的集合.因此,如果您为学生1运行此程序,您将获得一个包含学生2、3和4的集合.(如果您希望将原始学生保留为兄弟姐妹集合的一部分,那么将其运行为1将返回1, 2,3和4,只需删除getAllSiblings()中的optional步骤.)

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 in getAllSiblings().)

从那里,您可以根据需要将集合转换为数组,或进行排序等.

From there, you can cast the collection to an array, or sort, etc. as needed.

这篇关于兄弟姐妹的Laravel口才关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆