2017-07-22 62 views
0

我想從我的Laravel 5.4應用程序中的多對多關係獲取字段值。在Laravel 5應用程序中獲取多對多關係的透視字段值

我已經按照我的MySQL數據庫表:

products 
+ id 
+ name 
+ ... 


nutrients 
+ id 
+ name 
+ ... 

products_nutrients 
+ product_id 
+ nutrient_id 
+ value 

產品營養素表都有它的等效雄辯模型(產品營養)正確地工作多對多的關係他們之間的IP。

我需要列出具有某些營養素值的所有產品。我知道想要的營養素,所以我可以在查詢中設置它。 結果應該像集合/數組以下元素組成:

- product name 
- value of nutrient id 1 for product 
- value of nutrient id 2 for product 
- value of nutrient id 3 for product 

我怎樣才能弄清楚用雄辯的查詢生成器或在原始的SQL查詢最壞的情況下?我想避免foreach循環的解決方案。

我試圖實現它,但沒有成功。我會很高興有任何幫助。謝謝

回答

0

我設法通過原始SQL查詢來弄明白:

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) 

這裏也是雄辯的方式實現與上面相同:

$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'); 
1

使用->pivot屬性。從docs

正如您已經瞭解的,處理多對多關係需要存在一箇中間表。雄辯提供了一些非常有用的方式來與這個表進行交互。例如,假設我們的User對象有許多與其相關的Role對象。訪問這個關係之後,我們可以使用的機型樞軸屬性訪問中間表:

$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

+0

我知道這種方式來實現它,但它不是最佳。我想通過使用一個查詢來解決它,而不是foreach循環。 – zyx4sdk

+0

@ zyx4sdk我敢肯定,在這種情況下,您已經擁有'Product'實例,因爲您正在獲取產品名稱,所以此代碼只會創建一個查詢。此foreach循環不會在此代碼中創建N + 1個查詢。 –

+0

@AlexeyMezenin如果您指定加載產品的每個子代,這將僅創建一個查詢。要做到這一點,你可以使用''' - > load('nutrients')'''。查看更多https://laravel.com/docs/5.4/eloquent-relationships#eager-loading – Treast