我有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
]);
}
我的主要问题是:
- 这不能用作交易,即失败不会造成后退。
- 我不确定我将模型关系带来他们的全部潜力。
基本上可以进行两个改进。您的每个问题一个。
-
要将所有内容包裹在事务中,您可以将
create
语句放在DB::transaction(...)
块中。供参考,请看手册。还有另一种使用其中描述的交易的方法。 -
创建
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((;