Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何用多个外键查询pivot表Laravel 5_Php_Laravel_Laravel 5 - Fatal编程技术网

Php 如何用多个外键查询pivot表Laravel 5

Php 如何用多个外键查询pivot表Laravel 5,php,laravel,laravel-5,Php,Laravel,Laravel 5,我有以下表格结构: | products | product_options | product_option_values | product_option_to_product | +----------+-----------------+-----------------------+---------------------------+ | id | id | id | id

我有以下表格结构:

| products | product_options | product_option_values | product_option_to_product |
+----------+-----------------+-----------------------+---------------------------+
| id       | id              | id                    | id                        |
|          |                 |                       | product_id                |
|          |                 |                       | product_option_id         |
|          |                 |                       | product_option_value_id   |
我的亲戚是这样的:

// Product.php
public function options()
{
    return $this->belongsToMany('App\ProductOption', 'product_option_to_product', 'product_id', 'product_option_id')->withPivot('product_option_value_id', 'product_id');
}

// ProductOption.php
public function values()
{
    return $this->belongsToMany('App\ProductOptionValue', 'product_option_to_product', 'product_option_id', 'product_option_value_id')->withPivot('product_id');
}
$products = Product::with(['options.values' => function($q) {
    $q->join('products', 'products.id', '=', 'product_option_to_product.product_id');
}])->first();
现在,当我尝试这个:

$products = Product::with('options')->with('options.values')->first();

我得到了所有可能的选项值,因为它不使用产品id来加载选项值

有人知道我如何确保它只加载属于该产品的值吗

我可以在产品上建立一个直接与选项值的关系,但我确实需要将它们附加到它们所属的选项上

编辑:

我试过这样的连接:

// Product.php
public function options()
{
    return $this->belongsToMany('App\ProductOption', 'product_option_to_product', 'product_id', 'product_option_id')->withPivot('product_option_value_id', 'product_id');
}

// ProductOption.php
public function values()
{
    return $this->belongsToMany('App\ProductOptionValue', 'product_option_to_product', 'product_option_id', 'product_option_value_id')->withPivot('product_id');
}
$products = Product::with(['options.values' => function($q) {
    $q->join('products', 'products.id', '=', 'product_option_to_product.product_id');
}])->first();
但它给出了同样的结果

我现在实施了一个非常糟糕的修复,在我看来,我执行了一个小检查:

@if($value->pivot->product_id == $product->id)
    <div class="checkbox">
        <label>
            <input type="checkbox" name="{{ $option->id }}" value="{{ $value->id }}"> {{ $value->language->name }}
        </label>
    </div>
@endif
@if($value->pivot->product\u id==$product->id)
{{$value->language->name}
@恩迪夫

但是,我觉得这不对。

您的问题在于,表
product\u options
中的记录不知道您正在检索的产品

根据您在问题中提到的数据库结构,我写了以下几行:

$product = App\Product::with('options')->with('options.values')->first();
foreach ($product->options as $option) {
    foreach ($option->values as $value) {
        printf(
            "Product: %s, Option: %d, Value: %d\n",
            $product->id,
            $option->id,
            $value->id
        );
    }
}
上面的代码只是打印特定产品的选项和值的可能组合。我使用的关系与您在应用程序中创建的关系相同

加载该代码时,Eloquent(Laravel的ORM)在数据库中运行以下查询:

-- Retrieves the first product
select * from `products` limit 1;

-- Retrieves all options using the product_id as condition
select `product_options`.*, `product_option_to_product`.`product_id` as `pivot_product_id`, `product_option_to_product`.`product_option_id` as `pivot_product_option_id`, `product_option_to_product`.`product_option_value_id` as `pivot_product_option_value_id` 
from `product_options` inner join `product_option_to_product` on `product_options`.`id` = `product_option_to_product`.`product_option_id` 
where `product_option_to_product`.`product_id` in ('1')

-- Retrieves all values using the option_id as condition
select `product_option_values`.*, `product_option_to_product`.`product_option_id` as `pivot_product_option_id`, `product_option_to_product`.`product_option_value_id` as `pivot_product_option_value_id`, `product_option_to_product`.`product_id` as `pivot_product_id` 
from `product_option_values` inner join `product_option_to_product` on `product_option_values`.`id` = `product_option_to_product`.`product_option_value_id` 
where `product_option_to_product`.`product_option_id` in ('1', '2')
正如您所看到的,最后一个查询没有使用
product\u id
作为检索值的条件,因为
product\u options
表不包含对
products
表的引用

最后,我得到了和你一样的结果。与选项相关的所有值,尽管我正在搜索产品

最简单的解决方法是在调用关系时添加查询约束。像这样:

$product = App\Product::with('options')->with('options.values')->first();
foreach ($product->options as $option) {
    foreach ($option->values()->where('product_id', $product->id)->get() as $value) {
        printf("PRO: %s, OPT: %d, VAL: %d<br>\n", $product->id, $option->id, $value->id);
    }
}
通过这种方式,您可以使用相应的
选项\u id
获取特定产品的所有值(由其
$product->id
给出)

要在模板中使用上述查询的结果,您只需对复选框名称做一个小的更改:

<div class="checkbox">
    <label>
        <input type="checkbox" name="{{ $value->option_id }}" value="{{ $value->id }}"> {{ $value->language->name }}
    </label>
</div>

{{$value->language->name}

谢谢您的回答,这似乎是一个很好的解决方案。还没有尝试过,但是最后一个foreach循环是否会产生额外的查询,或者它是否可以处理已经检索到的结果?如果是这样的话,我更喜欢我自己的解决方案,因为产品的限制,不幸的是,它会做一些额外的查询。顺便说一句,您似乎正在尝试使用尽可能多的ORM方法,但有时直接依赖查询生成器并不是一个坏主意。尤其是为了获得一些性能增益。在这种情况下,我的解决方案不是更快吗?;)这取决于表中的值总数。如果表中有很多值,则必须循环检查所有值以查找其产品。与为每个选项多查询一次相比,它可能更慢,占用更多内存。我刚刚用一个可选的解决方案更新了我的答案,这个解决方案使用了一个查询生成器。我没有这样想过。我同意你的解决方案。谢谢