I have a model in Laravel called Player
. This player data is pulled from an external API. I am trying to update this external data on a scheduled basis from the external API. The external API data is the authoritative source on what should be in the players
table.
What I currently have is two collections, one is the data from the database, the other is the external API data. I constructed new Player
models in a collection based on the API data.
What I essentially have right now is this:
Collection $playersInDatabase; // Eloquent Collection of type Player Collection $playersFromApi; // Collection of type Player
The $playersFromApi
data is just the JSON API data converted into new Player models and added to the collection.
My problem is that I can’t just wipe the whole players
table as I am only modifying a subset of the table at a time. Is there an effective way to use Laravel to compare these two? I want to add any new Player models to the database that don’t exist, update any existing Player model that has differing data, and then also delete any records that the API data no longer has but are still in the database (stale records).
The only way I can think of to do this involves iterating over the collections multiple times to accomplish what I want to do and I feel like there is an easier more elegant way to do this that better utilizing the framework.
For reference here is what the players
table looks like. I am currently using seeder data:
Advertisement
Answer
You could do something like this. No comparisons necessary, just updateOrCreate()
and delete any ids not updated for the corresponding faction in a single DB call.
// 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();