如何更新值多对多 Laravel
Posted
技术标签:
【中文标题】如何更新值多对多 Laravel【英文标题】:How update values Many To Many Laravel 【发布时间】:2021-06-01 11:29:03 【问题描述】:如何更新 laravel 中的编辑字段?
我试过sync()方法,用atach()分离 不成功,我请你帮忙。
我非常感谢任何可以帮助我的人
记住,我已经设法用create方法保存了值,按照代码:
我的控制器:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Pedido;
use App\Models\Cliente;
use App\Models\Produto;
class PedidosController extends Controller
/**
* mostrar conteudo no index
*
* @return \Illuminate\Http\Response
*/
public function index()
$pedidos = Pedido::orderBy('id', 'asc')->paginate(2000);
return view('pedidos.index', compact('pedidos'));
/**
* Mostra o form para criar um novo pedido.
*
* @return \Illuminate\Http\Response
*/
public function create()
$clientes = Cliente::all();
$produtos = Produto::all();
return view('pedidos.create', compact('clientes', 'produtos'));
/**
* armazena um novo pedido pra enviar ao BD
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
$request->validate([
'status' => 'required',
'clientes_id' => 'required',
'produtos_id' => 'required'
]);
$pedido = Pedido::create($request->only([
'pedidos_id',
'produtos_id',
'clientes_id'
]));
$cliente = Cliente::find($request->clientes_id);
$pedido->clientes()->save($cliente);
$produto = Produto::find($request->produtos_id);
$pedido->produtos()->attach($produto);
return redirect()->route('pedidos.index')
->with('success', 'Pedido cadastrado com sucesso');
/**
* Exibe um pedido
*
* @param \App\Models\Pedido $pedido
* @return \Illuminate\Http\Response
*/
public function show(Pedido $pedido)
return view('pedidos.show', compact('pedido'));
/**
* Exibe um pedido para edição
*
* @param \App\Models\Pedido $pedido
* @return \Illuminate\Http\Response
*/
public function edit(Pedido $pedido)
$clientes = Cliente::all();
$produtos = Produto::all();
return view('pedidos.edit', compact('pedido', 'clientes', 'produtos'));
/**
* Atualiza um pedido no BD
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Pedido $pedido
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Pedido $pedido)
$request->validate([
'status' => 'required',
'clientes_id' => 'required',
'produtos_id' => 'required',
]);
$pedido->update($request->all());
return redirect()->route('pedidos.index')
->with('success', 'Pedido atualizado com sucesso');
/**
* Remove um pedido do BD
*
* @param \App\Models\Pedido $pedido
* @return \Illuminate\Http\Response
*/
public function destroy(Pedido $pedido)
$pedido->delete();
return redirect()->route('pedidos.index')
->with('success', 'Pedido deletado com sucesso');
我的编辑:
@extends('layouts.app')
@section('content')
<div class="container content">
<div class="row">
<div class="col-md">
<p class="text-center fs-1">Editar o pedido nº$pedido->id</b></p>
<div class="float-left">
<a class="btn btn-primary" href=" route('pedidos.index') " title="Voltar"> <i class="fas fa-backward "></i> </a>
</div>
</br>
@if ($errors->any())
<div class="alert alert-danger">
<strong>Ops!</strong> Há um problema com seu Pedido<br><br>
<ul>
@foreach ($errors->all() as $error)
<li> $error </li>
@endforeach
</ul>
</div>
@endif
<div class="row h-100">
<div class="col">
<form action=" route('pedidos.update', $pedido->id) " method="POST">
@csrf
@method('PUT')
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<label for="selectBox"> Cliente selecionado: </label>
<select style=width:400px name="clientes_id" class="form-control" onfocus="this.selectedIndex = -1;">
@foreach ($pedido->clientes as $cliente)
<option selected value=" $cliente->id"> $cliente->nome</option>
@endforeach
@foreach($clientes as $cliente)
<option value=" $cliente->id"> $cliente->nome</option>
@endforeach
</select>
</br>
<div class="custom-select">
<label for="selectBox"> Status selecionado: </label>
<select style=width:400px name="status" class="form-control" onfocus="this.selectedIndex = -1;">
<option selected> $pedido->status </option>
<option value=aberto>Em aberto</option>
<option value=pago>Pago</option>
<option value=cancelado>Cancelado</option>
</select>
</div>
</br>
<label for="selectBox"> Escolha um produto: </label>
<select style=width:400px class="form-control" name="produtos" id="selectBox" onfocus="this.selectedIndex = -1;" onchange="addProduct(options);">
@foreach ($produtos as $produto)
<option value=" $produto->id"> $produto->nome</option>
@endforeach
</select>
</br></br>
<table class="table">
<thead>
<tr>
<th>Código Produto</th>
<th>Produto selecionado</th>
<th>Remover</th>
</tr>
</thead>
<tbody id="tbody">
@foreach ($produtos as $key => $produto)
<tr>
<td>
<input type="hidden" name="produtos_id[$key]" value=" $produto->id"> $produto->id
</td>
<td>
$produto->nome
</td>
<td>
<input type='button' value='Remover' onclick='removeProduct()' />
</td>
</tr>
@endforeach
</tbody>
</table>
</br>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary">Enviar</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
var table = document.getElementById('tbody');
var count = linhas;
function addProduct(product)
table.innerhtml += "<tr><td><input type='hidden' name='produtos_id[" + count + "]' value='" + product[product.selectedIndex].value + "'>" + product[product.selectedIndex].value + "</td><td>" + product[product.selectedIndex].innerText + "</td><td><input type='button' value='Remover' onclick='removeProduct()'/></tr></td>";
count++;
function removeProduct()
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
count--;
</script>
@endsection
Pedido 模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Pedido extends Model
protected $table = 'pedidos';
public $timestamps = true;
protected $fillable = [
'status',
'clientes_id',
'created_at'
];
public function clientes()
return $this->hasMany(Cliente::class, 'id', 'clientes_id');
public function produtos()
return $this->belongsToMany(Produto::class, 'pedidos_produtos', 'pedidos_id', 'produtos_id');
产品模型
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produto extends Model
use HasFactory;
protected $table = 'produtos';
public $timestamps = true;
protected $casts = [
'preco' => 'float'
];
protected $fillable = [
'nome',
'descricao',
'preco',
'quantidade',
'created_at'
];
public function pedidos()
return $this->belongsToMany(Pedido::class, 'pedidos_produtos', 'produto_id', 'pedidos_id');
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produto extends Model
use HasFactory;
protected $table = 'produtos';
public $timestamps = true;
protected $casts = [
'preco' => 'float'
];
protected $fillable = [
'nome',
'descricao',
'preco',
'quantidade',
'created_at'
];
public function pedidos()
return $this->belongsToMany(Pedido::class, 'pedidos_produtos', 'produto_id', 'pedidos_id');
【问题讨论】:
请分享您的模型代码和架构。 attach 需要数组作为参数。使用 $pedido->produtos()->attach([$produto]); @r89human 部分正确,它可以带单个参数或数组,但应该是id
,所以attach($produto->id)
或 attach([$produto->id])
那么您的问题解决了吗?
@r89human 如果帮助github.com/wgerenutti/projetont
【参考方案1】:
您需要尝试此代码。它会起作用的。
$produtoId = [];
foreach ($produto as $pdt)
$produtoId[] = $pdt->id;
$pedido->produtos()->sync($produtoId);
$pedido->update($request->all());
【讨论】:
在sync()
之前不需要detach()
; sync()
执行 attach()
、detach()
和 updateExistingPivot()
多合一幕后工作:)
下一期Produto::find()
应该返回null
或单个Produto
实例,因此foreach()
完全没有必要。你的代码可以简单到$produto = Produto::find($request->produtos_id)
然后$pedido->produtos()->sync($produto->id);
,甚至$pedido->produtos()->sync($request->produtos_id);
。
我自己在聊天中检查了这段代码。出于某种原因 $produto = Produto::find($request->produtos_id);正在返回一个集合数组。
哦,真的吗?这很奇怪,但如果是这样的话,那么这段代码是正确的。非常有趣,因为 find()
应该只返回一个模型实例(或 null
作为后备)
是的。可能有多个具有相同“producto_id”的条目,它不是主键或架构有问题。很好的讨论。谢谢。以上是关于如何更新值多对多 Laravel的主要内容,如果未能解决你的问题,请参考以下文章
使用 Laravel 表单模型绑定和复选框更新多对多 Eloquent 关系
在 laravel 中使用多对多关系同步:PostgreSQL 数据透视表不更新