更新多列

时间:2019-02-22 05:26:26

标签: php laravel controller

我想更新一个产品的多个product_variant。同时,我也更新了产品名称。 我要更新的是:

Product-> name
Product_variant(can be multiple)->name & price

我尝试的代码:

$product = Product::findOrFail($id);
$product->name = $request->product_name;
$product->update();
for ($i = 0; $i < count($request->variant_name); $i++) {
        $variant = ProductVariant::where('product_id',$id)->get();
       $variant->variant_name = $request->variant_name[$i];
       $variant->variant_price = $request->variant_price[$i];
       $variant->update();
 }

视图中:

  <form action="{{ route('product.update',$product->id) }}" method="post">
    {{ method_field('PUT') }}
    {{ csrf_field() }}
    <label>{{ __('Product Name') }}</label>
    <input id="product_name" type="text" name="product_name" value="{{ $product->name }}" required autofocus>
    @foreach($product->product_variant as $variant)
            <label>{{ __('Variant') }}</label>
             <input id="product_name" type="text" name="variant_name[]" value=" 
                {{ $variant->variant_name }}" required autofocus>
              <input id="product_name" type="text" name="variant_price[]" value=" 
                {{ $variant->variant_price }}" required autofocus>
   @endforeach
      <button type="submit" class="rounded btn btn-primary">
              {{ __('Update') }}
       </button>                
  </form>

5 个答案:

答案 0 :(得分:1)

在循环中,当从数据库中获取$ variants时,将获得ProductVariant的集合(一对多关系),这就是为什么出现错误“ Method Collection :: update不存在”的原因。 ”。 Laravel get()返回ProductVariant的集合。

您似乎要更新具有相同名称和价格的一种产品的所有product_variant。因此,最好将product_variants放入循环之外,然后遍历所获得的集合进行循环。

$product = Product::findOrFail($id);
$product->name = $request->product_name;
$product->update();
$variants = ProductVariant::where('product_id',$id)->get(); // This return a collection of ProductVariant
foreach ($variants as $variant) {

    $variant->variant_name = $request->variant_name;
    $variant->variant_price = $request->variant_price;
    $variant->update();
}

但是,如果您需要使用从请求中获得的不同名称和价格来更新一种产品的变体,则首先需要更改html中文本输入的名称属性:

<input id="product_name" type="text" name="variant_name_{{$variant->id}}" value=" {{ $variant->variant_name }}" required autofocus>

<input id="product_name" type="text" name="variant_price_{{$variant->id}}" value=" {{ $variant->variant_price }}" required autofocus>

然后在您的代码中:

$product = Product::findOrFail($id);
$product->name = $request->product_name;
$product->update();
$variants = ProductVariant::where('product_id',$id)->get(); // This return a collection of ProductVariant
foreach ($variants as $variant) {

    $nameIdentifier = "variant_name_" . $variant->id;
    $priceIdentifier = "variant_price_" . $variant->id;
    $variant->variant_name = $request->$nameIdentifier;
    $variant->variant_price = $request->$priceIdentifier;
    $variant->update();
}

此外,由于您希望在请求中进行一组操作,因此我更喜欢进行数据库事务处理。在这种情况下,如果操作过程中出现任何问题,则可以安全地回滚。 https://laravel.com/docs/5.7/database#database-transactions

希望它会有所帮助:)

答案 1 :(得分:0)

尝试以下操作:

您需要使用first()代替get()

$product = Product::findOrFail($id);
$product->name = $request->product_name;
$product->update();
for ($i = 0; $i < count($request->variant_name); $i++) {
       $variant = ProductVariant::where('product_id',$id)->first();
       $variant->variant_name = $request->variant_name[$i];
       $variant->variant_price = $request->variant_price[$i];
       $variant->save();
 }

答案 2 :(得分:0)

您正在通过雄辩地使用get()方法来调用collection,该方法返回的是称为collection的数据数组,并且update()函数可以在单个对象而不是对象数组上调用。

@if (Model.CF_DateOfBirth.HasValue)
                                        {
                                            var today = DateTime.Today;
                                            var months = DateTime.Today;
                                            var age = today.Year - Model.CF_DateOfBirth.Value.Year;
                                            var mons = months.Month - Model.CF_DateOfBirth.Val`enter code here`ue.Month;
                                            if (Model.CF_DateOfBirth > today.AddYears(-age) && Model.CF_DateOfBirth>months.AddMonths(-mons))
                                            {
                                                age--; mons--;
                                            }
                                            <i class="" style="color:cadetblue">&nbsp;&nbsp;Date of birth:&nbsp;&nbsp;</i><b style="color:teal">@Convert.ToDateTime(Model.CF_DateOfBirth).ToShortDateString().ToString()</b> <span>&nbsp;&nbsp;(&nbsp;<b>@age</b>Years &nbsp;<b>@mons</b> Months)</span>

                                        }

}

如果您想获取集合并更新每条记录,则循环该集合并在其中执行逻辑,如下所示。

for ($i = 0; $i < count($request->variant_name); $i++) {
    $variant = ProductVariant::where('product_id',$id)->get(); //here you are doing mistake change get() to first() then it should work
   $variant->variant_name = $request->variant_name[$i];
   $variant->variant_price = $request->variant_price[$i];
   $variant->update(); // change update function to save(); since update function requires array of data which you want to send to database in your case you are calling update function without sending any data.

答案 3 :(得分:0)

尝试此代码:

$details = ProductVariant::where('product_id',$id)->get();

foreach ($details as $key => $detail) {
   $detail->variant_name = $request->get('variant_name')[$key];
   $detail->variant_price = $request->get('variant_price')[$key];
   $detail->save();
}

我希望这会有所帮助。

注意:-假设针对特定ID的产品变体行数和输入变体行数相同。

但是我建议您在variant label表中添加唯一的Product Variants列,以根据变量的标签更新值。

答案 4 :(得分:0)

尝试一下,

$details = ProductVariant::where('product_id',$id)->get();

if ($details->count() > 0) {
  foreach ($details as $key => $detail) {
      $detail->variant_name = $request->get('variant_name')[$key];
      $detail->variant_price = $request->get('variant_price')[$key];
      $detail->save();
  }
}