更新 Laravel 中的数据数组

Update data array in Laravel

我正在尝试更新 table 中的数据,作为数组从表单发送。

但是它发生在控制器的更新方法中,它接收数组但它只获取数组的最后一个值并在table中更新它。

我提交的表单数据是这样的 select 下垂:

<div class="input-group">
    <select name="product_id[]" class="js-basic-single form-select" data-width="100%">
        @foreach($products as $product)
            <option value="{{ $product->id }}" @if($product->id == $value->product_id) selected @endif>{{ $product->name }}</option>
        @endforeach
    </select>
</div>

如果来自product_id字段:

array:2 [▼ 
  0 => "2" 
  1 => "1" 
]

我让它在我的控制器中像这样更新:

for ($i=0; $i<count($request->quantity); $i++) {
    DB::table('quote_detail')
        ->where('quote_id', $id)
        ->update([
            'product_id'    => $request->product_id[$i],
            'quantity'      => $request->quantity[$i],
            'measure_id'    => $request->measure_id[$i]
    ]);
}

但它只插入并重复 1 作为数据库中的唯一值。

id | quote_id | product_id | 
 1 |        2 |          1 | 
 2 |        2 |          1 |

正确的应该是这样的:

id | quote_id | product_id | 
 1 |        2 |          2 |  
 2 |        2 |          1 |

花点时间了解您在这里做什么。

假设从请求传入的数据就像

['product_id' => [2,1], 'quantity' => [2,5], 'measure_id' => [3,4]];

for 循环将 运行 2 次 (count($request->quantity))。 quote_id = $id 标识的记录写入数据库的值将是:

  • 第一次循环运行s时:product_id: 2 quantity:2 measure_id: 3

  • 第二次循环运行s时:product_id: 1 quantity:5 measure_id: 4(同一条记录的值被覆盖)

因此最后一次迭代后的值将保持不变。

另一个是您正试图通过 non-primary 键来识别要更新的记录 - quote_detail [=103= 中可以有多个记录] 在 quote_id 字段中具有相同的值。

编辑:

I have the table (quotes), in it I store the primary data and in the table (quote_detail), the detail and it is related to the first.

Eloquent 方式
//Quote.php - Quote (eloquent) model class - table:quotes

public function quoteDetails()
{
    return $this->hasMany(QuoteDetail::class);
}
//QuoteDetail.php - QuoteDetail (eloquent) model class - table: quote_details

public function belongsTo()
{
    return $this->belongsTo(Quote::class);
}

在控制器中

$quote = Quote::findOrFail($id);
$count = 0;
for($i = 0; $i < count($request->quantity); $i++) {
    $quote->quoteDetails()
        ->updateOrInsert(
            /**
             * - Check for existing records with following column => value pairs
             * - Combination of quote_id & product_id will act as composite key to identify unique records in quote_details table
             * - Even better to have unique index using composite key quote_id + product_id
             */
            ['quote_id' => $quote->id, 'product_id' => $request->product_id[$i]],

            /** If a record exists it will be updated with following */
            ['quantity' => $request->quantity[$i], 'measure_id' => $request->measure_id[$i]]
        );

// If a matching record (quote_id + product_id) is not found then a new record will be inserted combining both arguments to the `updateOrInsert` method.
}

Laravel Docs - Queries - Update Statements

查询生成器方式
for($i = 0; $i < count($request->product_id); $i ++) {
    Db::table('quote_details')
        ->updateOrInsert(
            /**
             * - Check for existing records with following column => value pairs
             * - Combination of quote_id & product_id will act as composite key to identify unique records in quote_details table
             * - Even better to have unique index using composite key quote_id + product_id
             */
            ['quote_id' => $id, 'product_id' => $request->product_id[$i]],

            /** If a record exists it will be updated with following */
            ['quantity' => $request->quantity[$i], 'measure_id' => $request->measure_id[$i]]
        );

// If a matching record (quote_id + product_id) is not found then a new record will be inserted combining both arguments to the `updateOrInsert` method.
}
更新 - 更好的方法

更好的方法是通过 quote_details QuoteProduct 模型之间定义 many-to-many 关系 table 作为支点 table.

//Quote.php
public function products()
{
    $this->belongsToMany(Product::class, 'quote_details');
}
//Product.php
public function quotes()
{
    return $this->belongsToMany(Quote::class, 'quote_details');
}

然后在控制器中

$quote = Quote::findOrFail($id);

$syncData = [];

for($i = 0; $i < count($request->product_id); $i++) {
    $syncData[$request->product_id[$i]] = [
        'quantity' => $request->quantity[$i],
        'measure_id' => $request->measure_id[$i]
    ];
}

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

sync() 方法将仅保留 quote_details 中通过当前请求接收到 product_id(s) 的记录。

假设 table 中的早期值是:

id=1,quote_id=1,product_id=1,数量=2,measure_id=6.

新值是 quote_id=1,product_id=3,数量=2,measure_id=6

然后旧记录将被删除,新记录将被创建为

id=2(或任何自动增量),quote_id=1,product_id=3,数量=2,measure_id=6