在Laravel 5 app

时间:2017-07-22 11:37:14

标签: mysql sql laravel laravel-5 eloquent

我想在我的Laravel 5.4应用程序中从多个关系中获取字段值。

我的MySQL数据库中有以下表格:

products
 + id
 + name
 + ...


nutrients
 + id
 + name
 + ...

products_nutrients
 + product_id
 + nutrient_id
 + value

产品 营养素 表具有等效的Eloquent模型( 产品 营养素 ),正确地处理它们之间的多对多关系。

我需要列出所有含有某些营养成分的产品。我知道想要的营养素的ID,所以我可以在查询中设置它。 结果应该看起来像元素之后的集合/数组:

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

如何使用Eloquent查询构建器或在最坏的情况下在原始SQL查询中找出它?我想避免使用foreach循环解决方案。

我正在努力实现它,但没有成功。我会很高兴有任何帮助。谢谢

2 个答案:

答案 0 :(得分:2)

使用->pivot属性。来自docs

  

正如您已经了解的那样,处理多对多关系需要存在中间表。 Eloquent提供了一些与此表交互的非常有用的方法。例如,让我们假设我们的User对象有许多与之相关的Role对象。访问此关系后,我们可以使用模型上的pivot属性访问中间表:

$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

答案 1 :(得分: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)

这也是Eloquent方式实现与上述相同:

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