Using Laravel 5.3, I have a method in my Order
Eloquent model that returns a belongsToMany
or a hasMany
relationship depending on the value of a type
char attribute value.
Order
is itself a child of a MasterOrder
model as a one to many relationship.
---------------
* MasterOrder *
-------+-------
|
O2M
|
+----------------+------------------+
| | |
----+------- ----+------- -----+------
* Order * * Order * * Order *
* Type = O * * Type = C * * Type = S *
-+---------- -+---------- -+----------
| Offer |CreditPack | Shipment
| | |
M2M M2M O2M
The relation in the Order
model is the following
public function items()
{
$types = [
'S' => Shipment::class,
'O' => Discount::class,
'C' => CreditPack::class
];
if ($this->type == 'C') {
return $this->belongsToMany($types['C'], 'credit_pack_order')
->withTimestamps();
}
if ($this->type == 'O') {
return $this->belongsToMany($types['O'], 'discounts')
->withTimestamps();
}
return $this->hasMany($types[$this->type]);
}
When inserting the data I am able to attach()
offers and credit packs, and create()
shipments using my items()
method and it works without any issue.
Data is persisted in the database and everything is where I need it to be.
The problem is that I can't read through items()
if I eager load my relationships starting from the MasterOrder
model (even though I start from there when I insert the data).
I can read Order
data eager loading it from MasterOrder
, but it seems like it can't read Order
attributes when it tries to load items()
.
It is able to read them, instead, if I start from Order
.
Is there something I can do to avoid querying the database twice for every order?
Can anyone please explain me why do this happen?
I finally found a workaround while talking about the issue in a italian developers Facebook group.
Substantially I can tell the method what
type
comes out from the order as an argument of the function. This way it will know what to answer even if it didn't load the attributes.The relation becomes:
and I retrieve the data using