如何使用eloquent基于数据库关系来订购json响应

时间:2016-02-25 04:47:18

标签: php mysql laravel

我对Laravel很新,我正在试图弄清楚如何与Eloquent合作到目前为止这么好,但我陷入了我想做的事情:

我在数据库中有3个表4如果你计算迁移数:food,food_group和部分具有相同结构的食物,组和部分,并且id为主键和名称列

食物有

 |  id(primary)  |  name  | food_group_id (foreign key) | portion_id (foreign key |

一切都很好,因为我的路线中有一个很好的格式杰森

Route::get('/read', function() {

$categories = App\FoodGroup::with('Foods')->get();

 return Response::json(array('data' => $categories));
});

data: [
    {
       id: 1,
       name: "Frutas",
       foods: [
               {
                   id: 18,
                   name: "Acelga",
                   cant_portion: 2
               },
               {
                   id: 19,
                   name: "Espinaca",
                   cant_portion: 2
               },
              ]
    }
 ]

如果我使用App \ Portion改变App \ FoodGroup,它会给我相同的数组但现在作为Foreing Key部分订购

我需要的是首先订购FoodGRoup并在FFo_group的每个项目中订购,现在由第二个Foreing键订购,这是我可以有这样的东西

data: [
    {
       id: 1,
       name: "Frutas",
       portions:[
           id: 18,
           name: "Gr",  
           foods: [
               {
                   id: 18,
                   name: "Acelga",
                   cant_portion: 2
               },
               {
                   id: 19,
                   name: "Espinaca",
                   cant_portion: 2
               },
            ]
       ]           
    }
 ]

2 个答案:

答案 0 :(得分:2)

您预期的JSON会将foods显示为portions的孩子。为此,您需要设置此关系。

Portion模型上,您需要设置以下关系:

public function foods() {
    return $this->hasMany(Food::class);
}

通过此关系设置,您现在可以获得如下数据:

$categories = App\FoodGroup::with('portions.foods')->get();

这将加载您的食物组,然后它将这些部分加载到食物组中,然后它将食物加载到各部分。

修改

我可能会误解你的问题。我假设您在portions上定义了\App\FoodGroup关系。如果没有,您可以这样添加:

FoodGroup:

public function portions() {
    // the second parameter is the name of the pivot table.
    // in this case, your foods table connects your portions and food groups.
    return $this->belongsToMany(Portion::class, 'foods')->distinct();
}

编辑2

这个解决方案有点hacky,因为它将foods表视为数据透视表,尽管它不是专门为此而设计的。因此,foods表中有多个条目包含相同的密钥对值,这就是您获得重复相关模型的原因。

如果你在关系上抛出distinct(),这应该解决这个问题,因为它将消除从内部联接创建的重复项。上面的代码已被修改。

答案 1 :(得分:1)

基于图片(即您的表格),您发送的food_group与这些部分没有直接关系,因此您无法将food_group链接到这样的部分

  App\FoodGroup::with('portion.foods')

它应该是(这就是你在Builder :: portions()中得到BadMethodCallException的原因)

 App\FoodGroup::with('foods.portion')

因为食物群体有很多食物和食物有很多部分。所以你可以试试这样的东西

App\FoodGroup::with(['foods.portion'=>function($q){
   $q->orderBy('id')
}])->get();