Laravel — 3 модели со многими отношениями

#laravel #eloquent #eloquent-relationship

#laravel #красноречивый #красноречивый-отношения

Вопрос:

У меня есть 3 таблицы / модели, и я хотел бы собрать выходные данные в one-> ToMany-> ToMany. Я хочу получить данные из каждой из 3 таблиц в выходных данных. Я пробовал hasManyThrough, но это дает мне первое и последнее отношение к таблице. Я хочу, чтобы средняя (сквозная) таблица также выводилась.

Модели:

 student
 - id
 - name

course
 - id
 - student_id
 - name

level
 - id
 - course_id
 - level
 

Я хочу, чтобы выходные данные были в одном массиве / многомерном массиве, который выглядел бы следующим образом:

 student1 -> english -> 101
         -> history -> 104
                    -> 105

student2 -> english -> 201
                    -> 203
         -> history -> 202
         -> math -> 101

student3 -> english -> 302
         -> math -> 200
                 -> 201
         -> science -> 102
 

Затем я мог бы выполнить поиск по массиву и выгрузить его соответствующим образом, как указано выше. Похоже, что hasManyThrough не дает мне курсов, только вывод student1 -> 201.

hasManyThrough выглядит следующим образом:

 public function courselevels()
    {
        return $this->hasManyThrough('AppModelsLevel',
                                     'AppModelsCourse',
                                     'student_id',
                                     'course_id',
                                     'id',
                                     'id');

    }
 

Я также пробовал простой конструктор запросов, например:

 $userSoftware = DB::table('student')
    ->join('course', 'course.student_id', '=', 'student.id')
    ->join('level', 'level.course_id', '=', 'course.id')
    ->select('course.display_name', 'level.*')
    ->get();
 

Это работает до определенной степени, но у меня есть дубликаты для каждого возвращаемого элемента массива следующим образом:

 student1 -> english -> 101
student1 -> history -> 104
student1 -> history -> 105

student2 -> english -> 201
student2 -> english -> 203
student2 -> history -> 202
student2 -> math -> 101

student3 -> english -> 302
student3 -> math -> 200
student3 -> math -> 201
student3 -> science -> 102
 

Я в порядке либо с красноречивыми моделями, либо с настройкой hasThroughMany, либо с использованием обычного построителя запросов на контроллере.

Комментарии:

1. Установите отношение «один ко многим» между учащимся и курсами и отношение «многие ко многим» между курсами и уровнями. Затем вы можете легко загружать нужные данные, используя быструю загрузку с отношениями

Ответ №1:

в модели Student у вас должны быть отношения courses(), а в модели Course у вас должны быть отношения levels(). Затем, когда вам нужны все данные, с которыми вы запрашиваете with('courses.levels') .

 // student model
public function courses()
{
    return $this->hasMany(Course::class);
}

// Course model
public function levels()
{
    return $this->hasMany(Level::class);
}

$student = Student::with('courses.levels')->get();

// loop through courses
foreach ( $student->courses as $course ) {
  
  // $course->levels
}
 

Комментарии:

1. Я не знал о таких красноречивых отношениях и связывал их. Это сработало отлично.