【问题标题】:Eloquent belongsToMany and Three Tables (Including Pivot)Eloquent belongsToMany 和三个表(包括 Pivot)
【发布时间】:2018-05-30 01:43:01
【问题描述】:

我正在使用 Laravel 框架进行电子商务项目。我有一个产品表、一个风味表和一个风味产品表(我相信这被称为数据透视表)。我有一个 Product 模型和一个 Flavor 模型(根据我的阅读,没有必要为数据透视表创建模型)。

在 Product 模型中我定义了以下关系:

public function flavors()
{
    return $this->belongsToMany('App\Flavor');
}

在 Flavor 模型中我定义了以下关系:

public function products()
{
    return $this->belongsToMany('App\Product');
}

现在,在我的产品控制器中,我尝试了以下操作:

$flavors = Product::select('id')->with('flavors')->get();

它被发送到适用的视图 (product.blade.php)。

在 product.blade.php 我有以下内容:

@foreach ($flavors as $flavor)
  <select id="product-flavor" class="bs-select">
     <option value="{{ $flavor }}">{{ $flavor }}</option>
  </select>
@endforeach

那么,给我的是什么?好吧,它向我展示了以下内容:

{"id":1,"flavors":[{"id":1,"name":"Cake Batter","created_at":"2018-05-29 20:12:56","updated_at":"2018-05-29 20:12:56","pivot":{"product_id":1,"flavor_id":1}},{"id":2,"name":"Caramel Coffee","created_at":"2018-05-29 20:48:25","updated_at":"2018-05-29 20:48:25","pivot":{"product_id":1,"flavor_id":2}},{"id":3,"name":"Chocolate Milkshake","created_at":"2018-05-29 20:49:09","updated_at":"2018-05-29 20:49:09","pivot":{"product_id":1,"flavor_id":3}},{"id":4,"name":"Cookies &amp; Cream","created_at":"2018-05-29 20:49:50","updated_at":"2018-05-29 20:49:50","pivot":{"product_id":1,"flavor_id":4}},{"id":5,"name":"Vanilla Milkshake","created_at":"2018-05-29 20:50:16","updated_at":"2018-05-29 20:50:16","pivot":{"product_id":1,"flavor_id":5}}]}

我绝对不想要所有这些。我想要的只是通过数据透视表检索与该产品关联的风味名称。

我该如何继续?

编辑

以下代码在 ShopController.php 中(关于如何检索和显示产品):

/**
 * Display the specified resource.
 *
 * @param  string  $slug
 * @return \Illuminate\Http\Response
 */
public function show($slug)
{
    $product = Product::where('slug', $slug)->firstOrFail();
    $mightAlsoLike = Product::where('slug', '!=', $slug)->mightAlsoLike()->get();

    return view('product')->with([
        'product' => $product,
        'mightAlsoLike' => $mightAlsoLike,
    ]);
}

来自 web.php:

Route::get('/shop/{product}', 'ShopController@show')->name('shop.show');

【问题讨论】:

  • 与哪个产品相关联?
  • 当前显示的那个。
  • 嗯,您可以分享您检索该产品并显示它的代码吗?您如何知道要检索哪些产品的风味?现在,您的代码会获取所有产品。
  • 我希望我在编辑中添加的附加信息是您正在寻找的。根据产品的唯一 slug 检索产品。
  • 是的,这让你更清楚你想要什么。将为您解决问题。

标签: mysql laravel laravel-5 eloquent has-and-belongs-to-many


【解决方案1】:

您在这里所做的是告诉 Laravel 从所有产品中选择 id 并检索所有相关的风味。

Product::select('id') // <-- Will only select `id` attribute from the `products` table
    ->with('flavors') // <-- Will attach associated flavors to the product id
    ->get(); // <-- End the query (get all product ids and their flavours)

在您的情况下,您不想选择所有产品并且您已正确设置了关系。所以你应该做的是在你的原始查询上调用-&gt;with('flavors')(在这种情况下实际上不需要,因为你不会遇到n+1的问题,但仍然是很好的做法):

$product = Product::where('slug', $slug)->with('flavors')->firstOrFail();
$mightAlsoLike = Product::where('slug', '!=', $slug)->mightAlsoLike()->get();

return view('product')->with([
    'product' => $product,
    'mightAlsoLike' => $mightAlsoLike,
]);

然后在视图中调用$product-&gt;flavors

@foreach ($product->flavors as $flavor)
  <select id="product-flavor" class="bs-select">
     <option value="{{ $flavor }}">{{ $flavor }}</option>
  </select>
@endforeach

上述视图代码将按原样运行,而无需在查询中实际调用-&gt;with('flavors')-&gt;with(...) eager 加载关系,是在加载多个父项时显式调用的好习惯,以避免 n+1 问题(性能!)。

但在您的情况下,您只展示了一种产品的风味,因此明确调用它并没有真正的优势(除了更清晰的代码)。

编辑以解决评论:

<select id="product-flavor" class="bs-select">
@foreach ($product->flavors as $flavor)
    <option value="{{ $flavor->id }}">{{ $flavor->name }}</option>
@endforeach
</select>

您会看到多个选择,因为您在循环内打印整个选择,而不是仅打印选项。

要显示当前风味的任何属性,只需调用属性名称:例如$flavor-&gt;name

【讨论】:

  • 好的,谢谢!我实现了它,它正在到达某个地方,除了它显示风味表中的所有内容(id、名称、创建时间、更新时间)而不仅仅是名称,它还提供多个下拉列表,而不是每个风味只有一个下拉列表。我将继续尝试排除故障,但我们将不胜感激任何其他建议。
  • 查看编辑。只需像在任何其他模型上一样调用 $flavor 上的属性
  • 好的,谢谢你,明白了(成功!)。知道为什么我会为每种口味提供一个下拉菜单,而不是为所有口味提供一个下拉菜单吗?我假设这很简单......
  • 您正在迭代与当前模型相关的风味。如果你想遍历所有这些,你需要一个单独的查询来获取所有的口味并迭代那些
  • 所以您希望选择仅显示 1 个选项,但在该 1 个选项中显示所有口味?只需将foreach 移动到&lt;option&gt; DOM 中。不太了解您使用的插件或显示的插件,因此无法提供太多帮助
猜你喜欢
  • 2016-09-10
  • 2018-01-31
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 2019-05-12
  • 2019-12-30
相关资源
最近更新 更多