Php Laravel避免子表中的重复条目
我有很多条形码的产品,当我在产品编辑页面中添加/删除/编辑产品的条形码时,它会再次保存条形码(PS:我知道问题的来源,但不确定解决方案) 逻辑 因此,当我在产品编辑页面中时,我希望发生以下情况:Php Laravel避免子表中的重复条目,php,laravel,Php,Laravel,我有很多条形码的产品,当我在产品编辑页面中添加/删除/编辑产品的条形码时,它会再次保存条形码(PS:我知道问题的来源,但不确定解决方案) 逻辑 因此,当我在产品编辑页面中时,我希望发生以下情况: 如果当前条形码已更改,请更新它们 如果删除了任何当前条形码,请将其从数据库中删除 如果列表中添加了任何新条形码,请将其添加到数据库中 基本上是我正在寻找的sync()功能,但基于我的模型关系,我认为使用sync()不是一个选项 代码 产品型号 public function barcodes() {
sync()
功能,但基于我的模型关系,我认为使用sync()
不是一个选项
代码
产品型号
public function barcodes()
{
return $this->hasMany(Barcode::class, 'product_id', 'id');
}
protected $fillable = [
'product_id', 'serial_number',
];
public function product()
{
return $this->belongsTo(Product::class);
}
条形码型号
public function barcodes()
{
return $this->hasMany(Barcode::class, 'product_id', 'id');
}
protected $fillable = [
'product_id', 'serial_number',
];
public function product()
{
return $this->belongsTo(Product::class);
}
控制器(更新功能)
正如我前面提到的我知道问题的来源,但不确定它的解决方案
,重复保存数据的问题是我正在使用$barcode=new barcode代码>
额外的
为了清楚起见,当我向后端发送更新请求时,我的数据就是这样的
问题:
为了实现所需的逻辑,我应该在代码中更改什么?我认为这是因为当数据发送到服务器时,它们也包含旧数据
这段代码总是创建一个新代码,而不更新它
$barcode=新条码;
.
.
.
$barcode->save();
也许你可以这样做
foreach($request->input('barcode')作为$bb)
{
如果(!empty($bb['serial_number']){//请确保不保存空值
/*更新具有序列号的行或创建一个序列号*/
条形码::更新或创建([
“序列号”=>$bb[“序列号”]//如果序列号是唯一的。
“产品id”=>$product->id
], [
“序列号”=>$bb[“序列号”],
“产品id”=>$product->id,
]);
}
}
使用序列号查找条形码并进行更新。
未找到条形码时,创建新条形码
希望这能有所帮助。我就是这样为一对多关系创建同步功能的:
public function update(Request $request, $id)
{
$product = Product::find($id);
$product->name = $request->input('name');
if($product->save())
{
if(!empty($request->input('barcodes')))
{
$barcodeSync = []; // We will use this to save all the barcode id's that exist in the database.
foreach($request->input('barcodes') as $bb)
{
if(!empty($bb['serial_number'])){
$barcode = $product->barcodes()->updateOrCreate(
['id' => $bb['id'] ?? 0],
['serial_number' => $bb['serial_number']]
); // This will create a new barcode for the product if that barcode doesn't exist yet or update the existing barcode using it's id.
array_push($barcodeSync, $barcode->id); // This will add the id to the array of existing barcodes for this product.
}
}
$product->barcodes()->whereNotIn('id', $barcodeSync)->delete(); //Deletes all barcodes for this product that were not in the request.
}
}
}
这应该解决你的3个期望
这将更新与“id”和“产品id”匹配的任何条形码。(请注意,如果“序列号”不变,laravel实际上不会更新模型)
它将为产品创建或更新的所有条形码保存在$barcodeSync
数组中,以便您以后可以删除请求中不再存在的所有条形码$product->barcodes()->whereNotIn('id',$barcodeSync)->delete()代码>
它将创建传入请求的任何新条形码,因为新条形码在请求中没有“id”字段,它将查询id为0(0将不存在),这将触发创建新条形码并将其分配给产品。(为此,还应确保条形码模型的“id”字段不在$filleble
数组中,因为它会在每次创建新条形码时尝试将id设置为0,这将导致错误)
希望这对你有帮助 如果您是sql数据库,我建议您在数据库上放置复合键。然后是用户insertOrUpdate方法。注意这个!您的updateOrCreate()
方法可以更新另一个产品的条形码模型,并可以将其产品更改为当前产品。您应该按id和product_id进行查询,以免意外更改实际上不属于该产品的条形码。@RobertKujawa Hi。你说得很对!现在我修复代码。谢谢你的评论!谢谢,我会测试你的代码并告诉你结果。