Currently working on a very basic three table/model problem in Laravel and the proper Eloquent setup has my brain leaking.
COLLECTION -> coll_id, ...
ITEM -> item_id, coll_id, type_id, ...
TYPE -> type_id, ...
I can phrase it a thousand ways but cannot begin to conceptualize the appropriate Eloquent relationships:
COLLECTIONS have many ITEMS, each ITEM has a TYPE. Or, an ITEM belongs to a single COLLECTION, TYPES are associated with many ITEMS.
To me COLLECTION and ITEM are key, while TYPE is really additional reference data on a given ITEM; basically a category for the item.
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).
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.
Models:
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);
}
}
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.
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?
Thanks in advance!
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 ▶}
]
}
]
collection()
. AHasOne
would mean the Collection table has a foreign key to the Item table. Please check my updated answer. – newUserName02