Красноречивая связь между таблицами в Laravel

У меня есть три таблицы:

  1. collections, который имеет id, name
  2. genre_collection, который имеет id, genre_id, collection_id
  3. genres, который имеет id, name

Я хочу получить данные из коллекций с помощью Generes.

Коллекции Модель

class Collections extends Model{
    public function genres(){
        return $this->hasMany('App\Models\GenreCollectionRelationships', 'genre_id' , 'id');
    }
}

общая_коллекция

class GenreCollectionRelationships extends Model{
    public function genre(){
        return $this->hasOne('App\Models\Genres', 'id', 'genre_id');
    }
}

Контроллер поиска

class SearchController extends Controller{
    $collection->genres;
    foreach($collection->genres as $item){
        $item->genre;
    }
}

Этот код работает нормально. И выход

Действительный

"genres": [{
    "id": 1,
    "genre_id": 1,
    "collection_id": 1,
    "created_at": "2019-02-07 17:13:36",
    "updated_at": "2019-02-07 17:13:36",
    "genre": {
        "name": "Action",
        "meta": null
    }
}]

Есть ли способ, которым я мог бы напрямую получить вывод, как показано ниже

Ожидал

"genres": [ {
    "name": "Action",
    "meta": null
}]

Пробовал hasManyThrough, принадлежитToMany, но ничего не вышло.

Примечание. Я на ларавеле 5.7

Заранее спасибо.

почему вы сохраняете жанр_id в таблице коллекций? , он уже есть в таблице жанра_коллекции

Saurabh Mistry 07.02.2019 19:18

Спасибо. По ошибке я добавил это к вопросу. Удалил сейчас.

Alaksandar Jesus Gene 07.02.2019 19:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
72
5

Ответы 5

Вы можете создать свой собственный запрос для достижения того, что вы ищете. Попробуй это:

$collection = Collection
        ::join('genres', 'genre.id', '=', 'collections.genre_id')
        ->select('collections.*', 'genres.name','genre.meta')
        ->get();

Я ищу ответ с красноречивым отношением для меня, чтобы учиться. Спасибо за ответ

Alaksandar Jesus Gene 07.02.2019 19:22

Я нахожу ваш код немного сложным для понимания... Позвольте мне попробовать и посмотреть, правильно ли я понял...

В основном у вас есть две модели:

  • Модель Collection сохранена в таблице collections
  • Модель Genre сохранена в таблице genres

Поскольку у вас есть отношения «многие ко многим» между ними, вам нужна третья таблица, чтобы связать их обоих вместе.

Согласно соглашению об именах, Laravel ожидает, что вы назовете его на основе двух моделей, расположенных в алфавитном порядке. Таким образом, чтобы создать связь между коллекциями и жанрами, вам необходимо создать таблицу collection_genre, в которой collection_id используется в качестве ссылки на таблицу коллекций, а также genre_id для идентификации связанного жанра.

Затем вы можете определить свои отношения следующим образом:

class Collection extends Model {
    public function genres() {
       $this->belongsToMany(\App\Models\Genre::class);
    }
}

и

class Genre extends Model {
    public function collections() {
       $this->belongsToMany(\App\Models\Collection::class);
    }
}

Теперь я не уверен, как выглядит ваш контроллер, поскольку в вопросе есть неверный код, но я подозреваю, что вы хотите искать жанры для данной коллекции.

Ваш код может выглядеть так:

Class CollectionController extends Controller {

    function getGenres(Collection $collection) {
        return $collection->genres;
    }
}

Это вернет жанры для данной коллекции. Если вы хотите отформатировать это, вы можете создать для этого Eloquent Resource:

Class CollectionResource extends Resource {
    public function toArray() {
        return [
           'name' => $this->name,
           'meta' => $this->meta
        ];
    }
}

В вашем контроллере вы можете сделать:

Class CollectionController extends Controller {

    function getGenres(Collection $collection) {
        return CollectionResource::collection($collection->genres);
    }
}

в вашей коллекции модель

class Collections extends Model
{
    protected $table='collections';
    public $primaryKey='id';
    protected $fillable = ['name'];

    public function genres()
     {
            return $this->belongsToMany('App\Model\Genres','genre_collection','collection_id','genre_id')->withTimestamps();
     }

}

в вашей модели жанров

class Genre extends Model {

  protected $table='genres';
  public $primaryKey='id';
  protected $fillable = ['name'];


    public function collections()
    {
        return $this->belongsToMany('App\Model\Collections','genre_collection','genre_id','collection_id')->get();
    }

}

Вы создаете отношения «многие ко многим» между collections и genre, используя сводную таблицу genre_collection. В этом случае подходит принадлежитToMany. И вам не нужна никакая модель для таблицы жанра_коллекции.

Модель коллекций

class Collections extends Model
{
    public function genres(){
        return $this->belongsToMany('App\Models\Genres', 'genre_collection', 'genre_id', 'collection_id');
    }
}

Жанровая модель

class Genres extends Model
{

    public function collections(){
        return $this->belongsToMany('App\Models\Collections', 'genre_collection', 'collection_id', 'genre_id');
    }
}

SearchController

class SearchController extends Controller
{
    foreach($collection->genres as $item){
        $item->genre; // get genre info
    }
}

Нужно ли мне снова запускать цикл foreach. Разве нельзя использовать как $ collection- > жанры

Alaksandar Jesus Gene 07.02.2019 20:45

Я предполагаю, что вы хотите получить доступ к Generic непосредственно из collection . Если это так, вы можете определить отношение «многие ко многим» в модели коллекции непосредственно к общей модели для доступа к ней. См. это : https://laravel.com/docs/5.7/eloquent-relationships#many-to-many . Извините, если я ошибаюсь

Другие вопросы по теме