我们有两个模型“Foo”和“Bar”,如下图所示(一个Foo可以有很多条)。更新一对多关系条目而不触及未受影响的行
比方说,我们想从$_POST
更新Foo
模型值。由于Foo
与Bar
的关系,我们也想要更新Bar
模型,其值为相同的$_POST
。 Foo
更新过程与往常一样(即通过foo ID从数据库加载Foo
模型,然后加载$_POST
至Foo
模型并保存模型)。但Foo
可以有很多Bar
s,这就是为什么我们删除条形表中有$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
条目,我们必须删除旧的和添加新的。我们认为这种方法并不是最优的,因为如果我们有很多条目和用户更改,我们必须删除所有条目并再次插入相同的条目和更新的条目。 (就像上面的例子,即使“bar2”未被触摸,所有三个Bar
条目也将被删除)。
是否还有其他更好的方法比这一个(我们想忽略不变的行,只改变受影响的行)?
您可能会考虑只删除不在提交的$ _POST中的Bar。之后,插入忽略或替换为只添加新条。 – xangxiong
假设您使用$ bar获取相关的$ foo数据,当您通过id获取$ foo进行更新时,请创建一个比较算法,查看$ _POST数组与$ foo相关$ bar数据中的数据。然后你会知道该忽略什么以及要更新什么。 – dataskills
我会跟踪ID(s)...添加隐藏的ID字段,当条形图条目被提交时,会发布该隐藏的ID字段,与数据库进行比较,如果有更改,则会更新这些条目。帮助? – Hmmm