更新json列以及laravel中的其他列

时间:2018-01-13 09:20:40

标签: php json laravel eloquent

我想知道如何更新JSON列数据,同时还需要更新其他列。

当我在laravel网站上看到样本时,json专栏

就是这样的
DB::table('users')
            ->where('id', 1)
            ->update(['options->enabled' => true]);

但其他专栏呢?

这是我目前所拥有的:

public function update(Request $request, $id)
    {
        $order = Order::find($id);
        $this->validate($request, array(
            'payment_id'=>'nullable',
            'orderstatus_id' => 'required|numeric',
            'address_id' => 'required|numeric',
        ));

        $order = Order::where('id',$id)->first();
        $order->payment_id = $request->input('payment_id');
        $order->orderstatus_id = $request->input('orderstatus_id');
        $order->address_id = $request->input('address_id');

        $order->save();

        return redirect()->route('orders.index',
            $order->id)->with('success',
            'Order updated successfully.');
    }

我有一个名为product_name的列,它是Json类型的列,其中我有下面的数据示例,我想在其中编辑quantity个产品。

{"29": {"id": 29, "name": "effewf", "price": 24524, "quantity": 3, "attributes": [], "conditions": []}, "37": {"id": 37, "name": "test product", "price": 456346, "quantity": 2, "attributes": [], "conditions": []}}

正如您在此订单中看到的,我有两种产品,一种产品的数量为3,另一种产品的数量为2

2 个答案:

答案 0 :(得分:2)

Laravel文档中有一节arrays and JSON。执行此操作的方法是将$casts属性添加到Order模型:

protected $casts = [
    'product_name' => 'array',
];

在您的刀片视图和控制器中,您应该可以直接访问$order->product_name - 不再需要进行任何json_decode()次呼叫。

更新特定值时,请按照“编辑顺序”进行更新。看来,您可能希望将您的表单输入命名为类似的内容,以便轻松映射您的更新,即类似于:

@foreach($order->product_name as $data) 
    <label>Name:</label>
    <input
      type="text"
      name="product_name[{{ $data['id'] }}][name]"
      value="{{ $data['name'] }}"
    >

    <label>Price:</label>
    <input
      type="text"
      name="product_name[{{ $data['id'] }}][price]"
      value="{{ $data['price'] }}"
    >

    <label>Quantity:</label>
    <input
      type="number"
      name="product_name[{{ $data['id'] }}][quantity]"
      value="{{ $data['quantity'] }}"
    >
@endforeach

这意味着在您的控制器的update()方法中,您可以像平常一样使用从请求输入中获取的新值。如果要严格遵循文档中的格式,还应将其设置为新变量而不是直接设置,即

public function update(Request $request, $id)
{
    $order = Order::find($id);

    // ... other usual stuff

    // get original data
    $new_product_name = $order->product_name;

    // contains all the inputs from the form as an array
    $input_product_name = $request->input('product_name');
    // loop over the product array
    foreach ($input_product_name as $data_id => $data) {
        // loop over each input for the product in the view form
        foreach ($data as $key => $value) {
             // set the new value
             $new_product_name[$data_id][$key] = $value;
        }
    }
    // set the new data (should automatically serialize into JSON for storage)
    $order->product_name = $new_product_name;

    $order->save();
}

答案 1 :(得分:1)

处理此问题的最佳方法是为此数据创建模型和表格。

但是如果你想使用JSON,你可以在模型中使用casts属性:

protected $casts = [
    'product_name' => 'array',
];

然后,您将能够像使用数组一样使用选项:

$order = Order::where('id',$id)->first();
$order->payment_id = $request->input('payment_id');
$order->orderstatus_id = $request->input('orderstatus_id');
$order->address_id = $request->input('address_id');
$order->product_name[$request->product_id]['quantity'] = $request->new_product_quantity);
$order->save();

如果您不想使用演员表,可以手动转换数据:

$order->product_name = json_encode(
    json_decode($order->product_name, true)[$request->some_product_id]['quantity'] = $request->new_quantity
);