雄辩的查询给出了错误行中的数据

时间:2018-06-24 13:12:49

标签: laravel eloquent

不久前,我从Larvel开始了我的第一个项目,并遇到了一个奇怪的问题,即我遇到了一个Eelquent查询。

所以我有3张桌子:

|---------------------|------------------|------------------|
|       storage       |       items      | storage_contents |
|---------------------|------------------|------------------|
|         id          |        id        |        id        |
|---------------------|------------------|------------------|
|       user_id       |       name       |    storage_id    |
|---------------------|------------------|------------------|
|        name         |    description   |     item_id      |
|---------------------|------------------|------------------|
|     description     |       kcal       |      amount      |
|---------------------|------------------|------------------|
|                     |      img_url     |    expiry_date   |
|---------------------|------------------|------------------|
|                     |  always_on_list  |                  |
|---------------------|------------------|------------------|

在存储属于用户的地方,存储包含项,而storage_contents是这两者之间的数据透视表。

如果有人想知道为什么我不只是将expiry_dateamount放在Items表中,而是放在他们自己的数据透视表中,那是因为我打算让它成为用户可以在彼此的存储中使用彼此的物品。因此,例如,如果一个用户创建了Apple项目。当另一个用户开始输入时,他们会得到一个下拉菜单,其中包含从另一个用户选择先前创建的Apple产品的选项。但是,尽管名称,描述,图像和大卡可能相同,但每个用户的金额和有效期可能会有所不同。因此,我将其放在数据透视表中。

在我尝试运行此口才查询之前一切正常:

$item = Items::find($id)->storageContent()->get();

storageContent()是Items模型中的一种雄辩的关系:

public function storageContent(){

    return $this
        ->belongsToMany(Items::class,'storage_contents','item_id','storage_id')
        ->withPivot('amount','expiry_date');

}

但是由于某种原因,当我执行此查询时,我仅从第一个表项中获取数据(无论我输入了什么ID),但数据透视表数据正确的数据透视表。但是我无法终生发现为什么

要弄清楚我在此查询中得到的东西和期望得到的东西:

当我将查询放入Artisan修补匠中时

说我的“项目”表中有2个项目:

|-------------------|-------------------|
|       items       |       items       |
|-------------------|-------------------|
|       id: 1       |       id: 2       |
|-------------------|-------------------|
|     name: foo     |     name: bar     |
|-------------------|-------------------|
| description: null | description: null |
|-------------------|-------------------|
|    kcal: null     |    kcal: null     |
|-------------------|-------------------|
|   img_url: null   |   img_url: null   |
|-------------------|-------------------|
| always_on_list: 0 | always_on_list: 0 |
|-------------------|-------------------|

其中foo的数量为123,bar的数量为321。

在工匠修补匠中输入$item = Items::find(1)->storageContent()->get();时,我得到:

Illuminate\Database\Eloquent\Collection {#109
 all: [
   App\Items {#2337
     id: 1,
     name: "test1",
     description: "foo",
     kcal: null,
     img_url: null,
     always_on_list: 0,
     created_at: "2018-06-24 15:12:03",
     updated_at: "2018-06-24 15:12:03",
     pivot: Illuminate\Database\Eloquent\Relations\Pivot {#2332
       item_id: 1,
       storage_id: 1,
       amount: 123,
       expiry_date: null,
     },
   },
 ],
}

这符合我的期望,但是当我做$item = Items::find(2)->storageContent()->get();时,我会得到:

Illuminate\Database\Eloquent\Collection {#109
 all: [
   App\Items {#2337
     id: 1,
     name: "test1",
     description: "foo",
     kcal: null,
     img_url: null,
     always_on_list: 0,
     created_at: "2018-06-24 15:12:03",
     updated_at: "2018-06-24 15:12:03",
     pivot: Illuminate\Database\Eloquent\Relations\Pivot {#2332
       item_id: 2,
       storage_id: 1,
       amount: 321,
       expiry_date: null,
     },
   },
 ],
}

我不希望得到什么,我希望得到:

Illuminate\Database\Eloquent\Collection {#109
 all: [
   App\Items {#2337
     id: 2,
     name: "test2",
     description: "bar",
     kcal: null,
     img_url: null,
     always_on_list: 0,
     created_at: "2018-06-24 15:12:03",
     updated_at: "2018-06-24 15:12:03",
     pivot: Illuminate\Database\Eloquent\Relations\Pivot {#2332
       item_id: 2,
       storage_id: 1,
       amount: 321,
       expiry_date: null,
     },
   },
 ],
}

也许你们当中有人知道我做错了什么?

2 个答案:

答案 0 :(得分:0)

在您的Storage模型中:

public function items() 
{ 
    return $this->belongsToMany(
        Items::class,
        'storage_contents',
        'item_id',
        'storage_id'
    )->withPivot('amount','expiry_date'); 
}

并查询:

$storage = Storage::where('id', $id)->with('items')->firstOrFail();

您可以通过以下方式访问视图中的枢轴列:

@foreach($storage->items as $item)
    <ul>
        <li>Amount - {{$item->pivot->amount}} </li>
        <li>Expiry - {{$item->pivot->expiry_date}} </li>
    </ul>
@enforeach

更新

  

我刚刚尝试过,这不是我想要的。如果我解释在哪里需要使用此查询,可能会有所帮助。当用户位于存储位置时,他/她可以看到该存储位置中有哪些项目。当用户单击某个项目时,需要弹出一个模式,并显示该项目的信息(名称,说明,大卡,金额,有效期)以填充该模式。

正如您在评论中所述,当用户访问存储中的项目时,您希望显示带有枢轴列的模式。因此,当用户首次访问存储时,您可能应该获得Storage及其所有项目,以使每个项目都有枢轴列。也许你想要我给你的东西的反面。您可以看到上面的更改。

但是,如果您只想从存储中选择一个项目,则可能已经有了storage或其id。然后,您可以尝试以下方法:

$storage = Storage::findOrFail($storageId)

然后您可以使用以下方法获得一个物品:

$items = $storage->items()->where('id', $itemId)->firstOrFail();

这可能会对您有所帮助。

答案 1 :(得分:0)

抱歉,暂时没有回复。我只是再次查看了我的问题/代码,发现了另一个似乎可以解决我的问题的解决方案。

因此,我以前在Items模型中有这种关系:

公共函数storageContent(){

return $this
    ->belongsToMany(Items::class,'storage_contents','item_id','storage_id')
    ->withPivot('amount','expiry_date');
}

但是我想我误解了应该在那输入哪些行,导致storage_id,因为相关键没有意义(回想起来)。原因是,如果我仅将其更改为id(又称id表中的Item行),就像这样:

公共函数storageContent(){

return $this
    ->belongsToMany(Items::class,'storage_contents','item_id','id')
    ->withPivot('amount','expiry_date');
}

它的工作方式与我期望的一样。

我仍然要感谢大家为我提供帮助并试图为我的问题找到解决方案的人。