Reputation: 320
I would like to get field value from pivot on many to many relationship in my Laravel 5.4 application.
I have following tables in my MySQL database:
products
+ id
+ name
+ ...
nutrients
+ id
+ name
+ ...
products_nutrients
+ product_id
+ nutrient_id
+ value
products and nutrients tables have its equivalent Eloquent model (Product and Nutrient) with properly working many to many relationship between them.
I need to list all products with values of certain nutrients. I know id of wanted nutrients, so I can set it in query. Result should look like collection/array following of element:
- product name
- value of nutrient id 1 for product
- value of nutrient id 2 for product
- value of nutrient id 3 for product
How can I figure it out using Eloquent query builder or in the worst case in raw SQL query? I want to avoid solution with foreach loop.
I am trying to achieve it but without success. I would be glad of any help. Thank you
Upvotes: 1
Views: 1702
Reputation: 320
I managed to figure it out by raw SQL query:
SELECT product.name, protein.value as protein, fats.value as fats, carbo.value as carbo
FROM products product
LEFT JOIN products_nutrients protein ON (product.id = protein.products_id AND protein.nutrients_id = 1)
LEFT JOIN products_nutrients fats ON (product.id = fats.products_id AND fats.nutrients_id = 2)
LEFT JOIN products_nutrients carbo ON (product.id = carbo.products_id AND carbo.nutrients_id = 3)
Here is also Eloquent way to achieve the same as above:
$query = DB::table('products')
->join('products_nutrients as protein', function ($join) {
$join->on('products.id', '=', 'protein.products_id');
$join->where('protein.nutrients_id', '=', 1);
})
->join('products_nutrients as fats', function ($join) {
$join->on('products.id', '=', 'fats.products_id');
$join->where('fats.nutrients_id', '=', 2);
})
->join('products_nutrients as carbo', function ($join) {
$join->on('products.id', '=', 'carbo.products_id');
$join->where('carbo.nutrients_id', '=', 3);
})
->select('name', 'protein.value as protein', 'fats.value as fats', 'carbo.value as carbo');
Upvotes: 0
Reputation: 163758
Use the ->pivot
attribute. From docs:
As you have already learned, working with many-to-many relations requires the presence of an intermediate table. Eloquent provides some very helpful ways of interacting with this table. For example, let's assume our User object has many Role objects that it is related to. After accessing this relationship, we may access the intermediate table using the pivot attribute on the models:
$user = App\User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->created_at;
}
https://laravel.com/docs/5.4/eloquent-relationships#many-to-many
Upvotes: 2