Laravel:使用“子对象”数组将JSON对象解析为模型示例

j2qf4p5b  于 2023-02-05  发布在  其他
关注(0)|答案(2)|浏览(181)

在我的(Laravel)应用程序中,接收一个JSON,如下所示:

{
  "name": "order 1",
  "customer": "cus123",
  "orderItems": [
    {
      "amount": 1,
      "name": "cola",
      "price": "2.10"
    },
    {
      "amount": 3,
      "name": "fanta",
      "price": "2.00"
    },
  ]
}

我已经在Laravel中创建了两个模型,一个Order和一个OrderItem。我想将接收到的JSON解析为一个Order示例$order。我可以在OrderController中这样做:

class OrderController extends Controller
{
  public function store(Request $request) {
    $order = new Order();
    $order->forceFill($request->toArray());
  }
}

现在可以在控制器的store函数中访问$order->name$order->customer等属性。当我访问$order->orderItems时,我收到一个包含“orderItems but as array, not as instance of OrderItem”的数组。
我希望$order->orderItems返回一个OrderItem示例的数组。我在Order中尝试了以下操作,但这不起作用,因为'orderItems'不是OrderItem::class,而是一个具有多个“OrderItems”的数组。

protected $casts = [
    'orderItems' => OrderItem::class,
  ];

我怎样才能让$order->orderItems返回一个OrderItem示例数组呢?谢谢你的帮助!

km0tfn4u

km0tfn4u1#

尝试将以下内容添加到控制器

  • 验证
  • 手动存储您的订单
  • 手动存储您的每个订单项目

class OrderController extends Controller
{
  public function store(Request $request) 
  {
    $your_rules = [
       'name' => 'required|string',
       'customer' => 'required|string', // related to customer id ?
    ];

    $validated = $request->validate($your_rules);
    $order = Order::create([
       'name' => $validated['name'],
       'customer' => $validated['customer'], // is this customer id or name ?
    ]);

    // I assume you already declare relationship to OrderItem inside your Order model
    foreach ($validated['orderItems'] as $orderItem) {
        // this array only is optional
        $orderItem = Arr::only($orderItem, ['name', 'amount', 'price');

        $order->orderItems()->save($orderItem);
    }

    // reload saved order items
    $order->load('orderItems');

    dd($order);
  }
}

也可以在一个命令中创建多个子项。

$order->orderItems()->saveMany([
    new OrderItem(['name' => '...', ... ]),
    new OrderItem(['name' => '...', ... ]),
]);

阅读此处了解更多信息https://laravel.com/docs/9.x/eloquent-relationships#the-save-method
您可以将其作为额外的自定义方法移动到模型中。例如:

public function saveOrderItems(array $orderItems): void
{
   $this->orderItems()->saveMany($orderItems);
}

你称之为$order->saveOrderItems($orderItems);
附言
不要忘记在Order模型中声明关系。

public function orderItems()
{
    return $this->hasMany(OrderItem::class);
}
3xiyfsfu

3xiyfsfu2#

我想你对整个模型关系感到困惑。检查文档here,你需要在你的订单和订单项模型之间定义正确的关系和外键。
那么你的模型应该是这样的;

//Order.php
class Order extends Model {

    protected $fillable = [
        'name',
        'customer',
    ];

    public function items() {
        return $this->hasMany(OrderItem::class);
    }
    
}

//OrderItem.php
class OrderItem extends Model {

    protected $fillable = [
        'amount',
        'name',
        'price'
    ];

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

那你的店法

public function store( Request $request ) {

    $request->validate([
        'name' => 'required',
        'customer' => 'required|exists:customers_table,id',
        'orderItems' => 'required|array'
    ]);

    $order = Order::create( $request->except('orderItems') );

    $items = $order->items()->createMany( $request->input('orderItems') );
}

相关问题