【问题标题】:Eloquent Relationship Between Tables in LaravelLaravel 中表之间的雄辩关系
【发布时间】:2019-07-01 22:32:07
【问题描述】:

我有三张桌子:

  1. collections 其中有 id, name
  2. genre_collection 其中有 idgenre_idcollection_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, belongsToMany,但没有成功。

注意。我在 laravel 5.7

提前致谢。

【问题讨论】:

  • 为什么要在收藏表中保存genre_id? ,它已经在genre_collection表中
  • 谢谢。我错误地将它添加到问题中。立即删除。

标签: php laravel eloquent eloquent-relationship


【解决方案1】:

您可以构建自己的查询来实现您正在寻找的内容。试试这个:

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

【讨论】:

  • 我正在寻找一个有雄辩关系的答案供我学习。感谢您的回答
【解决方案2】:

我发现您的代码有点难以理解... 让我试试看我是否理解正确......

你基本上有两个模型:

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

【讨论】:

    【解决方案3】:

    在你的收藏模型中

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

    【讨论】:

      【解决方案4】:

      您正在使用genre_collection 数据透视表在collectionsgenre 之间创建多对多关系。在这种情况下,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');
          }
      }
      

      搜索控制器

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

      【讨论】:

      • 我是否需要再次运行 foreach 循环。是不是不能像 $collection->genres 这样使用
      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 2019-11-06
        • 2018-07-24
        • 1970-01-01
        • 2020-07-23
        • 1970-01-01
        • 1970-01-01
        • 2016-09-06
        • 2018-11-12
        • 1970-01-01
        相关资源
        最近更新 更多