在数据库中插入多对多关系使我在null上调用成员函数sync()

时间:2020-08-05 21:07:55

标签: arrays laravel many-to-many

我有一个many to many关系。

Quote Model

public function products(){
    return $this->belongsToMany(Product::class);
}

Product Model

public function quotes(){
    return $this->belongsToMany(Quote::class);
}

我从输入表单收到Controller的详细信息。输出如下:

array:39 [▼ 
"_token" => "NgcHxCjpGUe1ot8nJr4Z8VFuA3DG9VprKWqRu5yk"
"quote_id" => "52" 
20 => "0"
10 => "0"
11 => "0"
12 => "0"
13 => "0"
14 => "0"
15 => "0"
16 => "0"
17 => "0"

"quote_id"表示在上述输入表单之前的步骤中创建的引用。 quote_id从表单中的隐藏输入字段传递到控制器。在上方的数组中,$key表示product_id,而$value表示产品的数量。

我正在尝试将数据插入table product_quote

Schema::create('product_quote', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('product_id');
        $table->unsignedBigInteger('quote_id');
        $table->integer('qty');
        $table->timestamps();
    });

这是我的代码:

$data = $request->toArray();
$quote_id = $data['quote_id'];
    unset($data['quote_id']);
    $quote = Quote::query()->findOrFail($quote_id);
    foreach (array($data) as $key => $value){
        $quote->products->sync($data);
        $quote->save();
    }

在那之后我仍然需要添加产品数量,但是我遇到一个错误:在null上调用成员函数sync()。

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

这是对馆藏与关系的误解。

在Laravel中,如果您有相关产品,则可以访问该关系。

$quote->products(); // returns belongsToMany relation query

要访问集合,请作为属性对其进行访问。

$quote->products; // returns a collection with the products

在您的情况下,您将其作为一个集合进行访问。如果您收到的是空错误,则可能还有其他问题,但是请首先将其更改为以下内容。

第二个设置枢轴字段的方法是在同步调用中使用键值数组,并使用键和结构中的值。您可能还应该取消设置令牌。相反,我通过使用除外过滤。更好的方法是对表单请求使用已验证。

您将需要调整数据以使其符合sync调用中的预期键值结构。在每次调用之间同步数据时,sync也应仅被称为sync。

$data = $request->toArray();

$quote = Quote::findOrFail($data['quote_id']); // calling query() is unnecessary

$products = collect($request->except(['_token', 'quote_id']))->
    ->mapWithKeys(function($item, $key) {
        return [$key => ['qty' => $item]];
    })->all();

$quote->products()->sync($products);

此解决方案利用mapWithKeys,它使您可以控制集合中的键和项目,这是一种不常用的集合方法。返回的闭包格式应为return ['key' => 'item'];,而不是return 'item';

答案 1 :(得分:0)

您需要使用products关系而不是集合。

$quote->products()->sync($data);
相关问题