在数据库中插入多对多关系让我调用一个成员函数 sync() on null

Insertion of many to many relationship in database gives me a Call to a member function sync() on null

我有 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()。

我做错了什么?

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

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

这是对集合与关系的误解。

在 Laravel 如果您的案例中有关系产品,要访问您将调用的关系。

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

要访问集合,您可以将其作为 属性。

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

在您的例子中,您将它作为一个集合来访问。你得到了一个空错误,其他可能是错误的,但首先将其更改为以下内容。

其次设置数据透视字段,在同步调用中使用键值数组,使用结构中的键和值。您可能还应该取消设置令牌。相反,我使用 except 过滤它。更好的方法是在表单请求上使用验证。

您将需要调整您的数据以适应同步调用的预期键值结构,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,它可以让你控制key和集合中的item,这是一种不常使用的集合方法。闭包的 return 格式应该是 return ['key' => 'item']; 而不是 return 'item';