Как выполнить красноречивое отношение «многие через многие ко многим» в laravel 5.2?

С учетом структур таблицы ниже:

table users
- id
- name

table group_user
- id
- group_id
- user_id

table groups
- id
- name

table events
- id
- name
- group_id

Мы можем видеть, что User имеет отношение к Event объекты, однако он должен пройти через отношение многих ко многим User к Group,

Я не уверен, какие отношения это называется … Это имеет-много-через-многие-ко-многим так как у него много Event объекты через отношения многих ко многим users-group_user-groups?

В любом случае, как мне составить запрос Laravel для этого?

1

Решение

Дано $id это идентификатор пользователя, выполняющего вызов, запрос SQL, который мы ищем, выглядит примерно так:

SELECT * FROM events WHERE group_id IN (
SELECT group_id FROM group_user WHERE user_id = $id
);

Так что если в вашем group_user Таблица, мы находим, что пользователь с user_id = 1 имеет следующие групповые отношения group_id = [1, 2, 3, 4, 5]результирующий запрос выглядит так: SELECT * FROM events WHERE group_id IN [1, 2, 3, 4, 5]; что мы ищем (события, связанные с этими группами).

  1. Открыть vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
  2. Вставьте следующий код после hasMany метод.

        /**
    * Define a many-through-many relationship.
    *
    * @param  string  $related
    * @param  string  $through
    * @param  string  $pivotTable
    * @param  string  $pivotKey
    * @param  string  $pivotThroughKey
    * @param  string|null  $firstKey
    * @param  string|null  $secondKey
    * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
    */
    public function manyThroughMany($related, $through, $pivotTable, $pivotKey, $pivotThroughKey, $firstKey = null, $secondKey = null)
    {
    $relatedModel = new $related; // App\Event
    $relatedTable = $relatedModel->getTable(); // events
    
    $firstKey = $firstKey ?: $this->getForeignKey(); // event_id
    
    $throughModel = new $through; // App\Group
    $throughTable = $throughModel->getTable(); // groups
    
    $secondKey = $secondKey ?: $throughModel->getForeignKey(); // group_id
    
    return $relatedModel
    ->whereIn($secondKey, function ($query) use ($pivotTable, $pivotKey, $pivotThroughKey)
    {
    return $query
    ->from($pivotTable)
    ->where($pivotKey, '=', $this->id)
    ->select($pivotThroughKey);
    })
    ->select($relatedTable . '.*');
    }
    
  3. Теперь для вашей модели. Чтобы использовать many-through-many отношение, перейти к вашему User модель и добавить следующее.

        public function events()
    {
    return $this->manyThroughMany('App\Event', 'App\Group', 'group_user', 'user_id', 'group_id');
    }
    

Параметры следующие:

  1. Название целевой модели, которая вас интересует (т.е. App\Event).
  2. Имя вторичной модели, через которую вы должны пройти (т.е. App\Group).
  3. Название сводной таблицы (т.е. group_user).
  4. Ключ сводной таблицы, ссылающийся на текущую модель (т.е. user_id).
  5. Ключ сводной таблицы, ссылающийся на вторичную модель (т.е. group_id).

Отказ от ответственности

Я действительно не знаю, существует ли такая вещь, как отношения «многие сквозь многие», или как она называется. Это просто код, который работал для меня, поэтому я хотел поделиться им с людьми, которые могут столкнуться с той же дилеммой, что и я.

Если есть более простой способ сделать это, пожалуйста, ответьте! Если есть вещи, которые я могу улучшить, пожалуйста, прокомментируйте. Благодарю.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]