Reputation: 23011
I have two models connected via a pivot table with an extra column to track the quantity
class Item extends Eloquent {
public function containers()
{
return $this->belongsToMany('Container', 'items_containers', 'item_id', 'container_id')->withPivot(['quantity']);
}
}
class Container extends Eloquent {
public function items() {
return $this->belongsToMany('Item', 'items_containers', 'container_id', 'item_id')->withPivot(['quantity']);
}
}
And a third model for my orders:
class OrderItem extends Eloquent {
public function originalItem()
{
return $this->hasOne('Item', 'id', 'item_id');
}
public function container() {
return $this->hasOne('Container', 'id', 'container_id');
}
}
What I want is to be able to get the specific data from the pivot table when eager loading the OrderItem models, so I only get the quantity where the item_id
and container_id
matches what's on the order item.
OrderItems::whereOrderId($orderId)
->with(['originalItem', 'container', '???'])
->get();
What's the best way to specify the relationship on the OrderItem, or load it in with with
?
Upvotes: 0
Views: 659
Reputation: 2913
The following returns what you want:
$orders = \App\OrderItem::select('item_orders.*', 'items_containers.quantity as quantity')->with('item', 'container')
->leftJoin('items_containers', function ($join) {
$join->on('items_containers.item_id', 'item_orders.item_id')
->where('items_containers.container_id', \DB::raw('item_orders.container_id'));
})
->get();
Then you can easily get the quantity.
$orders->first()->quantity;
That's it.
Upvotes: 2
Reputation: 23011
Major props to Morteza Rajabi for getting me on the right track. The first key was getting the specific relation, since while Items and Containers are a Many-to-Many relationship, the OrderItem has a One-to-One relationship with both the Item and the Container. In order to get the specific relationship quantity, I had to create an attribute specifying it:
public function getItemContainerQtyAttribute() {
if($this->item_id && $this->container_id) {
return $this->depoItem->containers()->where('items_containers.container_id', $this->container_id)->first()->pivot->quantity;
}
return null;
}
The item_id and container_id check is because this is a work in progress, and the OrderItems haven't always been created correctly, and some items don't have a container specified.
The next step was to autoload it with the appends
attribute within Eloquent:
protected $appends = ['item_container_qty'];
Now whenever I load $item = OrderItems::whereOrderId($order_id)->get();
, it will load the the pivot quantity automatically.
Upvotes: 1