Laravel中表之间的雄辩关系

时间:2019-02-07 18:04:01

标签: php laravel eloquent eloquent--relationship

我有三个表:

  1. collections,其中有idname
  2. genre_collection,其中有idgenre_idcollection_id
  3. genres,其中有idname

我想从具有类型的集合中检索数据。

收藏夹模型

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,belongsToMany ,但没有解决问题。

注意。我正在使用laravel 5.7

谢谢。

5 个答案:

答案 0 :(得分:0)

您可以构建自己的查询以实现所需的内容。试试这个:

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

答案 1 :(得分:0)

我发现您的代码很难遵循... 让我尝试看看我是否正确理解...

您基本上有两个模型:

  • 模型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;
    }
}

这将返回给定集合的类型。 如果要格式化它,可以为此创建一个雄辩的资源:

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

答案 2 :(得分:0)

在您的收藏模型中

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

}

答案 3 :(得分:0)

您正在使用collections数据透视表在genregenre_collection之间建立多对多关系。在这种情况下,belongsToMany是合适的。而且您不需要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
    }
}

答案 4 :(得分:0)

我假设您想直接从collection访问Generic。如果是这种情况,您可以在集合模型中直接定义一个多对多关系来访问通用模型。请参考:https://laravel.com/docs/5.7/eloquent-relationships#many-to-many。抱歉,如果我错了