如何通过3个以上的表建立Laravel雄辩的模型 [英] How to establish a Laravel Eloquent model through 3+ tables
问题描述
当前在Laravel中处理一个非常基本的三表/模型问题,而正确的口才设置使我的大脑漏水了.
Currently working on a very basic three table/model problem in Laravel and the proper Eloquent setup has my brain leaking.
COLLECTION-> coll_id,...
COLLECTION -> coll_id, ...
ITEM-> item_id,coll_id,type_id,...
ITEM -> item_id, coll_id, type_id, ...
TYPE-> type_id,...
TYPE -> type_id, ...
我可以用一千种方法来表述,但是不能开始概念化适当的口才关系:
I can phrase it a thousand ways but cannot begin to conceptualize the appropriate Eloquent relationships:
集合中有很多项目,每个项目都有一个类型.或者,一个ITEM属于一个集合,类型与许多ITEMS相关联.
COLLECTIONS have many ITEMS, each ITEM has a TYPE. Or, an ITEM belongs to a single COLLECTION, TYPES are associated with many ITEMS.
对我来说,COLLECTION和ITEM是关键,而TYPE实际上是给定ITEM上的其他参考数据;基本上是商品的类别.
To me COLLECTION and ITEM are key, while TYPE is really additional reference data on a given ITEM; basically a category for the item.
我的目标是建立一个解决方案,其中用户创建集合,将ITEMS添加到这些集合中,并且这些ITEMS与许多类型(它们也将定义)之一相关联.
My objective is to build a solution where users create COLLECTIONS, add ITEMS to those COLLECTIONS, and those ITEMS are associated with one of many TYPES (which they will also define).
我知道这个例子离其他作者,书本,类别不远.或城市,州,国家/地区示例,但实现这些模型框架并不能建立COLLECTION<-> ITEM<-> TYPE的完整连接,并且最明显的是,当尝试在COLLECTION中关联TYPES时失败.
I know this example isn't far from other Author, Book, Category; or City, State, Country examples but implementing those model frameworks doesn't build the full connection from COLLECTION<->ITEM<->TYPE and most obviously fails when trying to associate TYPES within a COLLECTION.
型号:
收藏
class Collection extends Model
{
protected $guarded = [];
public function items()
{
return $this->hasMany(Item::class);
}
public function types()
{
return $this->hasManyThrough(Type::class, Item::class);
}
}
ITEM
class Item extends Model
{
public function collection()
{
return $this->belongsTo(Collection::class);
}
public function type()
{
return $this->belongsTo(Type::class);
}
}
TYPE
class Type extends Model
{
public function item()
{
return $this->hasMany(Item::class);
}
}
这些模型在两个方向上的COLLECTION-> ITEM都运行良好,但是当我尝试集成TYPE时,轮子掉落了.根据我尝试的1000个变体,我要么在Tinker中得到NULL,要么正在TYPE中寻找一个ITEM_ID,该ID不存在也不应该存在.
These models have COLLECTION<->ITEM in both directions working well, but the wheels fall off when I try to integrate TYPE. Depending on the 1000 variations I've tried I either get NULL in Tinker or it's looking for an ITEM_ID in TYPE which doesn't and shouldn't exist.
更新模型以准确反映具有一个TYPE以及最终一组TYPES的ITEMS的解决方案是什么?
What would a solution be to update the model to accurately reflect ITEMS having one TYPE and the eventual set of TYPES within a COLLECTION?
提前谢谢!
更新:有效的<嵌套>嵌套解决方案-主要响应解决方案在COLLECTION中显示2个关系,无嵌套:
UPDATE: Working nested solution - the primary response solution was showing 2 relations at COLLECTION, no nesting:
class Collection extends Model
{
protected $guarded = [];
public function items()
{
return $this->hasMany(Item::class);
}
class Item extends Model
{
public function collection()
{
return $this->hasOne(Collection::class);
}
public function type()
{
return $this->belongsto(Type::class);
}
}
class Type extends Model
{
public function items()
{
return $this->hasMany(Item::class);
}
}
$collection->load('items.type');
dd($collection);
Collection {#280 ▼
#guarded: []
#connection: "mysql"
#table: "collections"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▶]
#original: array:5 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
**#relations: array:1** [▼
"items" => Collection {#285 ▼
#items: array:2 [▼
0 => Item {#288 ▼
#connection: "mysql"
#table: "items"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:13 [▶]
#original: array:13 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
**#relations: array:1** [▼
"type" => Type {#296 ▶}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [▶]
}
1 => Item {#289 ▶}
]
}
]
推荐答案
HasManyThrough
与Collection和Type之间的关系不正确. HasManyThrough
有点像将2个HasMany
关系链接在一起:
HasManyThrough
isn't the right relationship between Collection and Type. HasManyThrough
is kind of like chaining 2 HasMany
relationships together:
Country -> State -> City
注意所有箭头如何向一条方向移动.那是因为城市对国家有外键,国家对国家有外键.
Notice how the arrows all go one way. That's because City has a foreign key to State, and State has a foreign key to Country.
您的关系如下:
Collection -> Item <- Type
因此,Item具有用于Collection和Type的外键.在这种情况下,Collection和Type之间的关系实际上是BelongsToMany
,而Item表是联接表.
So Item has foreign keys to both Collection and Type. In this case, the relationship between Collection and Type is actually BelongsToMany
, and the Item table is the join table.
https://laravel.com/docs/5.8/eloquent -relationships#多对多
class Collection extends Model
{
protected $guarded = [];
public function items()
{
return $this->hasMany(Item::class);
}
public function types()
{
// Substitute your table and key names here
return $this->belongsToMany(Type::class, 'items_table', 'coll_id', 'type_id');
}
}
class Type extends Model
{
public function items()
{
return $this->hasMany(Item::class);
}
public function collections()
{
// Substitute your table and key names here
return $this->belongsToMany(Collection::class, 'items_table', 'type_id', 'coll_id');
}
}
class Item extends Model
{
public function collection()
{
return $this->belongsto(Collection::class);
}
public function type()
{
return $this->belongsto(Type::class);
}
}
如果要获取包含其项目的集合,以及每个项目下的相应类型,则可以执行以下操作:
If you want to get collections with their items, and the corresponding type under each item, you can do:
Collection::with(['items.type'])->get();
这篇关于如何通过3个以上的表建立Laravel雄辩的模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!