Laravel 5 - firstOrCreate()并删除旧项目?

时间:2016-09-13 23:20:25

标签: laravel laravel-5

真的不知道如何解决这个问题,但我有一个带有entry_id(外键)和键/值的元表,如下所示:

id | entry_id |     key     |     value     
-------------------------------------------
1       4         Fruit 1       Apple
2       4         Fruit 2       Banana
3       4         Fruit 3       Cantaloupe

我想使用新的键/值对entry_id 4Fruit 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/BananaFruit 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个要点吗?

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以查看它是否具有表示表中已存在的值的值。在您的情况下,您将检查keyvalue,如果它们已在数据库中作为一对存在,则不会删除它。但是,根据您提供的表结构,这似乎不是必需的,只是一个不必要的复杂功能。

答案 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');

然后使用新改进的列表再次运行您的代码。如果有帮助,请告诉我。