Красноречивая связь между таблицами в Laravel - PullRequest
0 голосов
/ 07 февраля 2019

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

  1. collections с id, name
  2. genre_collection с id, genre_id, collection_id
  3. genres с id, name

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

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

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

generic_collection

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 , но ничего не получилось.

Примечание.Я нахожусь на Laravel 5.7

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

Ответы [ 5 ]

0 голосов
/ 08 февраля 2019

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

0 голосов
/ 07 февраля 2019

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

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

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
    }
}
0 голосов
/ 07 февраля 2019

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

У вас есть две модели:

  • Модель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);
    }
}
0 голосов
/ 07 февраля 2019

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

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

}
0 голосов
/ 07 февраля 2019

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

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