如何在Laravel中基于另一个Collection来比较和更新Eloquent Collection

时间:2020-06-19 20:05:47

标签: php laravel collections eloquent laravel-collection

我在Laravel中有一个名为Player的模型。此播放器数据是从外部API中提取的。我试图按计划从外部API更新此外部数据。外部API数据是players表中内容的权威来源。

我目前有两个集合,一个是数据库中的数据,另一个是外部API数据。我根据API数据在集合中构造了新的Player模型。

我现在基本上拥有的是:

Collection $playersInDatabase; // Eloquent Collection of type Player
Collection $playersFromApi; // Collection of type Player

$playersFromApi数据只是转换为新的Player模型并添加到集合中的JSON API数据。

我的问题是我不能只擦除整个players表,因为我一次只修改表的一个子集。是否有使用Laravel比较这两者的有效方法?我想将任何不存在的新Player模型添加到数据库中,更新具有不同数据的任何现有Player模型,然后还删除API数据不再具有但仍在数据库中的任何记录(陈旧记录) 。

我想到的唯一方法是多次遍历集合以完成我想做的事情,我觉得有一种更简便,更优雅的方法可以更好地利用框架。

players表的外观仅供参考。我当前正在使用种子数据:

example table

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作。无需进行比较,只需updateOrCreate(),并在单个数据库调用中删除未为对应的派系更新的所有ID。

// the faction id you are querying from API
$faction_id = ...;

// for storing updated model ids
$updated_ids = [];

foreach ($playersFromApi as $playerFromApi) {

    // update record or create a new one
    $player = Player::updateOrCreate(
        [
            // conditions to meet
            '...' => $playerFromApi['...']
        ],
        [
            // data to update   
            '...' => $playerFromApi['...']
        ]

    );

    // store id of updated model
    $updated_ids[] = $player->id;
}


// delete models not updated
Player::where('faction_id',$faction_id)->whereNotIn('id',$updated_ids)->delete();