【发布时间】:2017-05-15 06:23:15
【问题描述】:
我们有两个模型“Foo”和“Bar”,如下图所示(一个 Foo 可以有多个 Bars)。
假设我们想用来自$_POST 的值更新Foo 模型。由于Foo 与Bar 的关系,我们还想用来自相同$_POST 的值更新Bar 模型。 Foo更新过程和往常一样(即通过foo ID从数据库中加载Foo模型,然后将$_POST加载到Foo模型并保存模型)。但是Foo 可以有很多Bars,这就是为什么我们从条形表中删除所有具有$fooId 的条目并从$_POST 向条形表创建新条目。
例如,用户打开表单,他可以在其中更改Foo 名称并添加/更改/删除许多条形名称。假设当前 foo 名称为“foo”,当前柱为“bar1”、“bar2”和“bar3”。用户将 foo 名称更改为“fooChanged”,同时将“bar1”更改为“bar10”并删除“bar3”。 注意:未触及“bar2”。提交表单后,控制器加载Foo 模型,加载 foo 更改(现在“foo”已更改为“fooChanged”)并保存模型。对于Bar 模型,它有点不同。首先,控制器删除所有具有$fooId 的条目,并创建具有batchInsert 的新条目(参见下面的代码)。
控制器:
public function actionUpdateFoo($fooId = null)
{
$foo = Foo::findOne($fooId);
$foo->load(Yii::$app->request->post());
$transaction = Yii::$app->db->beginTransaction();
if ($foo->save() && Bar::deleteAll(['foo_id' => $fooId]) && Bar::create($fooId, Yii::$app->request->post())) {
$transaction->commit();
} else {
$transaction->rollBack();
}
return $this->render('foo', [
'foo' => $foo,
]);
}
条形模型:
public static function create($fooId, $post)
{
$array = [];
foreach ($post['Bar'] as $item) {
array_push($array, [
'foo_id' => $fooId,
'name' => $item['name'],
]);
}
return Yii::$app->db->createCommand()->batchInsert(self::tableName(), ['foo_id', 'name'], $array)->execute();
}
我们面临的问题是,为了更新许多Bar 条目,我们必须删除旧条目并添加新条目。我们认为这种方法不是最优的,因为如果我们有很多条目并且用户只更改了一个,我们必须删除所有条目并再次插入相同的条目和更新的条目。 (就像上面的例子一样,所有三个Bar 条目都将被删除,即使“bar2”没有被触及)。
有没有比这个更好的方法(我们想忽略未更改的行,只更改受影响的行)?
【问题讨论】:
-
您可能会考虑只删除不在提交的 $_POST 中的 Bar。然后在此之后执行插入忽略或替换以仅添加新条。
-
假设您正在获取与 $bar 相关的 $foo 数据,当您通过 id 获取 $foo 进行更新时,创建一个比较算法,将 $_POST 数组与您的 $foo 相关$bar 数据。然后你就会知道要忽略什么以及要更新什么。
-
我会跟踪 id(s) ... 添加隐藏的 ID 字段,该字段将在提交 Bar 条目时发布,与 DB 进行比较,如果有任何更改,则更新这些条目。有帮助吗?