真的不知道如何解决这个问题,但我有一个带有entry_id(外键)和键/值的元表,如下所示:
id | entry_id | key | value
-------------------------------------------
1 4 Fruit 1 Apple
2 4 Fruit 2 Banana
3 4 Fruit 3 Cantaloupe
我想使用新的键/值对entry_id 4
和Fruit 1/Apple
列表更新Fruit 4/Dragonfruit
,如下所示:
id | entry_id | key | value
-------------------------------------------
1 4 Fruit 1 Apple
4 4 Fruit 4 Dragonfruit
以下是应该发生的三件事:
Fruit 1/Apple
没有改变,所以它应该保持不变。Fruit 4/Dragonfruit
在列表中是新的,因此应该添加。Fruit 2/Banana
或Fruit 3/Cantaloupe
,因此应删除它们。我尝试使用firstOrCreate()
这样:
// $metas is an array of the new list
foreach ($metas as $meta) {
$entry->entryMeta()->firstOrCreate([
'entry_id' => $entry->id,
'key' => $meta->key,
'value' => $meta->value
]);
}
其中包含了应该发生的3件事的前2个要点。删除不在新列表中的旧项目的最后一个要点不起作用(我理解,因为它不属于firstOrCreate()
)。
知道如何处理所有3个要点吗?
答案 0 :(得分:1)
由于您基本上想要替换表中具有entry_id == x
的所有条目,因此在您的模型上最简单的解决方案可能是这样的:
public function updateEntry(int $entryId, array $newFruits)
{
// delete old entries
self::where('entry_id', $entryId)->delete();
// create new ones
foreach ($newFruits as $fruit) {
self::save($fruit);
}
}
如果由于某种原因存在您不打算替换的现有行的额外数据,那么您可以修改此方法,检查$newFruits
以查看它是否具有表示表中已存在的值的值。在您的情况下,您将检查key
和value
,如果它们已在数据库中作为一对存在,则不会删除它。但是,根据您提供的表结构,这似乎不是必需的,只是一个不必要的复杂功能。
答案 1 :(得分:0)
我要做的是,获取新fruits数组的id然后根据id在表上执行whereNotIn(假设你的id在两种情况下保持不变)并删除结果 例如,
$ updateArray = NewFruits-> get() - > list(' id') - > toArray();
$ deleteFruits = Fruit :: whereNotIn(' id',$ updateArray) - > get();
foreach($ deleteFruits as $ deleteFruit){
$ deleteFruit->删除();
}
答案 2 :(得分:0)
好吧,这似乎是一个经典案例,你应该首先截断表格然后用你想要保留的条目运行你的查询。
DB::statement("SET foreign_key_checks = 0");
//Model::truncate();
Db::table('mytable')->truncate();
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
然后使用新改进的列表再次运行您的代码。如果有帮助,请告诉我。