'Access relation of pivot table in Laravel
I have three models Bill
, Product
and Process
. Bill
has a ManyToMany relationship with Product
and the pivot table have some extra fields. I write the Bill
model class like follow:
<?php
class Bill extends Model
{
function products(){
return $this->belongsToMany(\App\Product::class)
->withPivot('process_id') // the id of the Process
->withTimestamps();
}
}
The Process
model is a simple table with an id
and a name
. I am associating the id in the pivot table for reference the Process, the name could change over time but still referring the same concept so I can't associate the name.
The show page for a single Bill
lists the products associated in a table like follow:
@foreach($bill->products as $product)
<tr>
<td>{{$product->barcode}}</td>
<td>{{$product->pivot->process_id}}</td>
</tr>
@endforeach
So the problem is that I need the name of the process, but I have the id. I'm not sure how I could get the name.
Thanks
Solution 1:[1]
I think you can use an own Pivot Model, e.g. ProductBill
in order to achieve this.
class ProductBill extends Pivot {
public function process() {
return $this->belongsTo(Process::class);
}
}
By using this model in your products
relation on Bill
class Bill extends Model {
function products() {
return $this->belongsToMany(\App\Product::class)
->withPivot('process_id')
->using(ProductBill::class)
->withTimestamps();
}
}
When accessing $product->pivot
you should get an instance of ProductBill
now, hence you should be able to do the following:
<td>{{$product->pivot->process->name}}</td>
(Unfortunatelly I not able to doublecheck right now :/)
Solution 2:[2]
Without having a direct relation to Process
you will likely need to add a helper on your Product
model to get the name of Process
.
In your Product model:
public function processName($processId) {
return Process::where('id', $processId)->pluck('name')->first();
}
In your view:
<td>{{$product->processName($product->pivot->process_id) }}</td>
There may be a better way, but concept this should work.
Solution 3:[3]
I know it's not the most elegant of solutions. but you could always simply do:
Process::find($product->pivot->process_id)->name;
I wouldn't advice this though as you are looping through an array already, so the overheads to doing something like this would be quite large.
Another solution would be to create a Pivot class called say BillProductPivot
which would have a relationship to return both Product
and Process
, then when you call them you should be using eager loading to get the relationships. end product might look like this:
$bill->load('productPivots', 'productPivot.process', 'productPivot.product');
@foreach($bill->productPivots as $productPivot)
<tr>
<td>{{$productPivot->product->barcode}}</td>
<td>{{$productPivot->process->name}}</td>
</tr>
@endforeach
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | miken32 |
Solution 2 | Darryl E. Clarke |
Solution 3 |