我有一个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()。
我在做什么错了?
答案 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);