我們有兩個模型「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