雄辩的belongdomany和三个表(包括pivot)

vq8itlhq  于 2021-06-23  发布在  Mysql
关注(0)|答案(1)|浏览(311)


我正在使用laravel框架进行一个电子商务项目。我有一个products表、一个flavors表和一个flavor\u product表(我相信这被称为pivot表)。我有一个产品模型和一个风格模型(据我所知,没有必要为pivot表创建一个模型)。
在产品模型中,我定义了以下关系:

public function flavors()
{
    return $this->belongsToMany('App\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}}]}

我绝对不想要这些。我只想通过pivot表检索与该产品相关联的口味的名称。
我该怎么做?

编辑

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

ddarikpa1#

你要做的是让拉威尔选择 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)

在您的情况下,您不希望选择所有产品,并且您已经正确设置了关系。所以你应该打电话 ->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->flavors 在视图中:

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

上面的视图代码将按原样工作,而不实际调用 ->with('flavors') 在查询上。 ->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->name 例如。

相关问题