Laravel-与关系的多桌插入物



我有3个表格在创建订单时应该填充,我想知道这样做的最佳方法。

Orders
- id (pk)
- company_id
- address_id (join to items table)
- date
- source
- ...
Addresses
- id (pk)
- company_id
- name
- email
- address
- ...
Items
- id (pk)
- order_id (join to orders table)
- product_id
- qty
- ...

关系

  • 地址表属于订单表
  • 订单Hasmany项目
  • 我们有一个多倾斜(单个DB(结构,因此Company_ID用于分离公司之间的数据。订单和地址都属于公司。

创建

我的理解是,将首先创建地址以获取ID。然后将创建订单,然后是项目。

我还想确保如果任何插入失败,则不会保存任何数据(如在SQL Transaction中(。

我想知道是否有人可以将我的方向指向正确的方向?到目前为止,我有以下

$address = OrderAddress::create([
    'company_id' => Auth::user()->company_id,
    'name' => 'test test',
    'email' => 'test@test.com',
    'address' => '78 test street',
]);
$order = $address->order()->create([
    //'address_id' => populated by model
    'company_id' => Auth::user()->company_id,
    'date' => '2018-03-23',
    'source' => 'mystore'
]);
foreach($items as $item){
    OrderItem::create([
        'order_id' => $order->order_id,
        'product_id' => $item->product_id,
        'qty' => $item->qty
    ]);
}

我的主要问题是:

  1. 这不能用作交易,即失败不会造成后退。
  2. 我不确定我将模型关系带来他们的全部潜力。

基本上可以进行两个改进。您的每个问题一个。

  1. 要将所有内容包裹在事务中,您可以将create语句放在DB::transaction(...)块中。供参考,请看手册。还有另一种使用其中描述的交易的方法。

  2. 创建Order时使用的相同关系create方法也可以应用于OrderItems$order->items()->create([...])

最终代码段可能看起来像这样:

DB::transaction(function () {
    $address = OrderAddress::create([
        'company_id' => Auth::user()->company_id,
        'name' => 'test test',
        'email' => 'test@test.com',
        'address' => '78 test street',
    ]);
    $order = $address->order()->create([
        'company_id' => Auth::user()->company_id, // actually, this information is already available through the `address`
        'date' => '2018-03-23',
        'source' => 'mystore'
    ]);
    foreach($items as $item){
        $order->items()->create([
            'order_id' => $order->order_id,
            'product_id' => $item->product_id,
            'qty' => $item->qty
        ]);
    }
});

如果称为orderItems()而不是items()

,请确保更改该关系名称。

db :: trassaction(...(

db :: begintransaction((;

您可以通过回滚方法回滚交易:

DB :: Rollback((;

最后,您可以通过提交方法进行交易:

db :: commit((;

最新更新