Yii2-使用子记录更新记录
我有一个表单,允许用户添加许多子记录,在我的例子中,它们被称为“项”。更新主记录时,用户可以添加、编辑或删除子记录。一切都很好,但我正在寻找一个更好的方法来做到这一点 目前,在更新操作中,我首先删除所有现有的子记录。然后我保存表单post中的所有子记录Yii2-使用子记录更新记录,yii2,Yii2,我有一个表单,允许用户添加许多子记录,在我的例子中,它们被称为“项”。更新主记录时,用户可以添加、编辑或删除子记录。一切都很好,但我正在寻找一个更好的方法来做到这一点 目前,在更新操作中,我首先删除所有现有的子记录。然后我保存表单post中的所有子记录 public function actionUpdate($id) { $model = $this->findModel($id); if ($model->load(Yii::$app->request-&
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
// first delete all existing child records
Item::deleteAll(['parent_id' => $model->id]);
// get the new set of posted Items
$items = Yii::$app->request->post('Item');
if (!empty($items) && is_array($items)) {
// save each Item
foreach ($items as $index => $values) {
$item = new Item();
$item->attributes = $values;
$item->parent_id = $model->id;
$item->save();
}
}
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
]);
}
表单视图:
<form method="post" action="">
<?php foreach ($model->items as $index => $item): ?>
<?php echo Html::activeTextInput($item, "[$index]name"); ?>
<!-- Example output -->
<!-- <input id="item-0-name" name="Item[0][name]" value="Test" type="text"> -->
<a href="#">Remove this Item</a>
<?php endforeach; ?>
<button type="submit">Submit</button>
</form>
<a href="#">Add a new Item</a>
当用户单击“添加一个新项目”时,它只是使用JavaScript克隆最后一个项目,并用下一个值替换其索引
通常,用户不会更改任何子记录。因此,在这种情况下,删除和重新添加子记录的过程是毫无意义的
我想知道的是,有没有一种方法可以让我聪明地处理这个问题?例如:
- 仅当过帐项目数组中不存在子记录时才删除它们
- 仅当子记录与数据库中的记录不同时才编辑它们
- 仅添加数据库中当前不存在的新子记录
- 否则一切都保持原样
public function getItems() {
return $this->hasMany(Item::class, [/*...*/])->indexBy('id');
}
然后,您可以检查具有此ID的记录是否已存在,并执行更新/删除/创建操作:
// get the new set of posted Items
$items = Yii::$app->request->post('Item');
$existing = $model->items;
if (!empty($items) && is_array($items)) {
// save each Item
foreach ($items as $index => $values) {
if (!isset($existing[$index])) {
// create new item
$item = new Item();
$item->attributes = $values;
$item->parent_id = $model->id;
$item->save();
} else {
// update existing
$existing[$index]->attributes = $values;
$existing[$index]->save();
// remove from $existing array as already processed
unset($existing[$index]);
}
}
// right now $existing has only existing and not updated items - it means
// that they're not available in POST data so we should remove it
foreach ($existing as $item) {
$item->delete();
}
}
Item
model是否有ID或唯一字段?刚刚更新了我的原始帖子。项目模型具有ID主键。在我的表单中,项
以“表格”数组格式生成(从零开始)。!isset($existing[$index])
不起作用,表单字段使用默认数组索引而不是itemid
字段填充,第一个项目将始终具有索引0
,即使该项目已经存在且id为112
,但由于该字段已创建item-0-name
,它将假定id
为0
@MuhammadOmerAslam您确定吗?我做了一些测试,它工作正常-表单提交中保留了$index
中的索引。因此,只要表单中的$index
表示记录的ID,它就应该正常工作。我认为,看到OP中的当前表单字段,它们被填充为
,$index
这里不是项表的ID
?还是我错了?我想你错了,$this->hasMany(Item::class,[/*…*/])->indexBy('id')
应确保$model->items
将根据item ID进行索引。Hmm!您正在使用的indexBy()
将根据给定列对其进行索引,但完全忽略了这一点。
// get the new set of posted Items
$items = Yii::$app->request->post('Item');
$existing = $model->items;
if (!empty($items) && is_array($items)) {
// save each Item
foreach ($items as $index => $values) {
if (!isset($existing[$index])) {
// create new item
$item = new Item();
$item->attributes = $values;
$item->parent_id = $model->id;
$item->save();
} else {
// update existing
$existing[$index]->attributes = $values;
$existing[$index]->save();
// remove from $existing array as already processed
unset($existing[$index]);
}
}
// right now $existing has only existing and not updated items - it means
// that they're not available in POST data so we should remove it
foreach ($existing as $item) {
$item->delete();
}
}