在数据库中插入多对多关系让我调用一个成员函数 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';
我有 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';