首页 > 解决方案 > 如何比较和更新基于 Laravel 中另一个 Collection 的 Eloquent Collection

问题描述

我在 Laravel 中有一个名为Player. 此播放器数据是从外部 API 中提取的。我正在尝试从外部 API 定期更新这些外部数据。外部 API 数据是players表中内容的权威来源。

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

我现在基本上拥有的是:

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

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

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

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

作为参考,这里是players表格的样子。我目前正在使用播种机数据:

示例表

标签: phplaravelcollectionseloquentlaravel-collection

解决方案


你可以做这样的事情。无需比较,只需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();

推荐阅读