我有2个模型:ReceivedGoodsDetail
和StockInventory
。
当模型ReceivedGoodsDetail
执行actionCreate时,StockInventory
也会自动插入到表StockInventory
中。
我使用这个存储过程,这是我尝试过的:
public function actionCreate($id) {
$model = new ReceivedGoodsDetail();
$connection = \Yii::$app->db;
$transaction = $connection->beginTransaction();
$model->ID_Received_Goods = $id;
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$connection = Yii::$app->db;
$command = $connection->createCommand('{call usp_T_Received_Goods_Detail#InsertData(:ID_Received_Goods,:ID_Item, :Qty, :User)}');
$ID_Received_Goods = $model->ID_Received_Goods;
$ID_Item = $model->ID_Item;
$Qty = $model->Qty;
$User = Yii::$app->user->identity->username;
$command->bindParam(":ID_Received_Goods",$ID_Received_Goods,PDO::PARAM_STR);
$command->bindParam(":ID_Item", $ID_Item, PDO::PARAM_STR);
$command->bindParam(":Qty", $Qty, PDO::PARAM_INT);
$command->bindParam(":User", $User, PDO::PARAM_STR);
if ($command->execute() == 0) {
$transaction->commit();
} else {
$transaction->rollBack();
foreach ($model->getErrors() as $key => $message) {
Yii::$app->session->setFlash('error', $message);
}
}
return $this->redirect(['receivedgoodsheader/view', 'id' => $model->ID_Received_Goods]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
但是如果像上面的情况一样使用2个模型我很困惑
答案 0 :(得分:0)
不要害怕做这样的事情,这里使用存储过程没什么不好。但总的来说,你的代码并不干净,令人困惑。
首先,如果您正在使用存储过程,那么为什么不为ReceivedGoodsDetail(在INSTERT上)触发?恕我直言,触发器的一切都会简单得多。
以下是您实施的一些评论。
if
之前打开交易?如果验证失败,那么您的交易将不会被关闭
手动。ReceivedGoodsDetail
和StockInventory
我能理解的将在存储过程中创建usp_T_Received_Goods_Detail#InsertData
?transactions()
方法中对此模型进行交易。Yii::$app->db
,但稍后您可以轻松更改此特定模型的连接。最好(例如)扩展ActiveRecord(如果还没有)并重载insertInternal()
方法
为ReceivedGoodsDetail
。
在课程ReceivedGoodsDetail
中:
public function transactions() {
return [
'default' => self::OP_INSERT
];
}
protected function insertInternal($attributeNames = null) {
if (!$this->beforeSave(true)) {
return false;
}
$values = $this->getDirtyAttributes($attributes);
/* overrided part of code */
$connection = static::getDb();
$command = $connection->createCommand('{call usp_T_Received_Goods_Detail#InsertData(:ID_Received_Goods,:ID_Item, :Qty, :User)}');
$ID_Received_Goods = $model->ID_Received_Goods;
$ID_Item = $model->ID_Item;
$Qty = $model->Qty;
$User = Yii::$app->user->identity->username;
$command->bindParam(":ID_Received_Goods",$ID_Received_Goods,PDO::PARAM_STR);
$command->bindParam(":ID_Item", $ID_Item, PDO::PARAM_STR);
$command->bindParam(":Qty", $Qty, PDO::PARAM_INT);
$command->bindParam(":User", $User, PDO::PARAM_STR);
if($command->execute() != 0) {
return false;
}
/* end of overrided part */
$changedAttributes = array_fill_keys(array_keys($values), null);
$this->setOldAttributes($values);
$this->afterSave(true, $changedAttributes);
return true;
}
在你的行动中:
public function actionCreate($id) {
$model = new ReceivedGoodsDetail();
$model->ID_Received_Goods = $id;
if ($model->load(Yii::$app->request->post()) && $model->save(true)) {
return $this->redirect(['receivedgoodsheader/view', 'id' => $model->ID_Received_Goods]);
} else {
foreach ($model->getErrors() as $key => $message) {
Yii::$app->session->setFlash('error', $message);
}
return $this->render('create', [
'model' => $model,
]);
}
}
然后在创建表单上捕捉您的Flash消息。
P.S。还有一刻。使用path/to/model/{id}
端点是一种奇怪的做法
使用预定义的ID
来创建新实例。通常这看起来像POST path/to/model
。但这可能是您的业务逻辑的主题,所以我不知道它是否可以改进
P.P.S。这个例子没有经过测试(显然),所以这里可能会出现一些错误