在Eloquent中按类别列出用户的产品

时间:2015-02-09 21:23:10

标签: mysql sql laravel laravel-4 eloquent

Model excerpt

基本上我有以下表格,我试图按类别列出给定用户的所有产品。

示例:

{
 user_id: 1
 username: xpto
   categories: [{
      id: 1
      name: category_1
        products: [{
          id: 3
          name: prod1
        },
        {
          id: 3
          name: prod1
        }],
      id: 2
      name: category_2
        products: [{
          id: 6
          name: prod5
        }],
    }]
}

我从我想要的结果得到的最接近的是这个查询: App\User::with('products.category')->find(1);

已经花了很多时间考虑这个问题,但没有任何线索,开始感到绝望。请帮助。

1 个答案:

答案 0 :(得分:0)

Eloquent没有使用带有连接的单个查询来返回数据,当您需要过滤相关表时,这是一个糟糕的选择。你雄辩的电话:

App\User::with('products.category')->find(1);

...实际上会执行多次查询。

SELECT * FROM users WHERE id = 1

SELECT * FROM products JOIN product_user ... WHERE user_id = 1

SELECT * FROM categories WHERE id IN (...all of the category_ids returned from products...)

您应该立即看到问题:Eloquent首先查询所有用户并将其存储在一个数组中,然后使用单独的查询来获取产品和类别。因此,您无法按类别对用户进行排序。

有两种方法可以解决这个问题:

  1. 使用Eloquent获取包含产品和类别的用户(如您提供的示例中所示),然后迭代结果并提取(并排序)类别和产品。
  2. 使用连接构建正确的查询。

    User::select('users.name as user_name', 'products.name as product_name', 'categories.name as category_name')
            ->join('product_user', 'users.id', '=', 'product_user.user_id')
            ->join('products', 'product_user.product_id', '=', 'products.id')
            ->join('categories', 'products.category_id', '=', 'categories.id')
            ->orderBy('categories.name')
            ->get();
    
  3. 请注意,如果您的表共享列名,如id,name等,则需要指定列别名。