Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Burdyle's avatar

Seeking advice on structuring API and custom data in a single Model

I took the "Build a Video Game Aggregator" course, and it inspired me to create an app to manage data using IGDB as practice.

I decided to start by managing different platforms, but I'm having difficulty finding the optimal structure.

For example, I want to fetch different platforms from the IGDB API and add them to my database, but I also want the possibility to modify some information.

Here's a use case: I change the name of a platform and need to ensure that the name is unique. Additionally, I want the ability to revert to the original name fetched from IGDB. I also want to update all platforms via IGDB without overwriting my modifications.

What would be the best way to structure the database for platforms? I was thinking of having a single table called "Platforms" with a "name" field and another field like "custom_name" if I modify it. Or should "Platforms" be a pivot table with "ApiPlatform" and "CustomPlatform" tables, and in the "Platform" model, have a getter getNameAttribute that returns $this->custom->name ?? $this->api->name?

I'm fairly new to database structuring, so I imagine there might be a better way to go about this!

Thanks in advance for your help! 😊

0 likes
6 replies
martinbean's avatar

@burdyle I think you’re over-complicating the problem at hand a little.

I also don’t really understand why you would rename a platform. If by “platform” you mean something like PlayStation 5, why would you need to “rename” that in your application?

Burdyle's avatar

@martinbean for example, I would rename "Sega Megadrive" received in the igdb response to "Sega Genesis"

I know I will run into this issue with games too. For example, Power Strike for the Master System is named "Aleste" on igdb…

I want to be able to display my custom title, but I also want to show the original one.

Like I mentioned, my goal here is to practice so I’m overthinking and over-complicating things on purpose :p

martinbean's avatar

@Burdyle They’re just different names for the same entity, though. The console was called the “MegaDrive” here in the UK, and “Genesis” in other markets (i.e. the US). And if I make a request to the IGDB’s platforms endpoint, then it tells me such:

{
  "id": 29,
  "abbreviation": "Genesis/MegaDrive",
  "alternative_name": "Sega Genesis",
  "category": 1,
  "created_at": 1300959838,
  "generation": 4,
  "name": "Sega Mega Drive/Genesis",
  "platform_family": 3,
  "slug": "genesis-slash-megadrive",
  "updated_at": 1718027289,
  "url": "https://www.igdb.com/platforms/genesis-slash-megadrive",
  "versions": [
    64,
    622,
    623,
    624,
    625,
    626,
    627,
    628
  ],
  "checksum": "9dbdfd6d-4dae-3a0f-1d20-e12e6dc15b41"
}
Burdyle's avatar

@martinbean I get what you mean about the different names for the same entity. For this project though, I'm looking to implement a system that lets me customize these names while keeping the original ones intact. It’s kind of like on Discord, where you can rename a friend but still keep the original name available.

I'm doing this mainly as an exercise to practice managing data modifications while preserving original data. So, even though it might seem a bit over-complicated for practical use, it's great practice for me. For example, maybe a user would want to rename a recipe, or an admin would want to rename a product.

On second thought, with my current level of knowledge, it probably makes the most sense to go with a single Platform model. I’d have an original_name field and a name field, and use a getter method like getNameAttribute to return $this->name ?? $this->original_name.

What do you think?

Thanks for your insights and help! 😊

martinbean's avatar
Level 80

@Burdyle Then yes, have two columns: one to hold the “original” name and a second to hold a custom name.

1 like
LaryAI's avatar
Level 58

To address your requirement of managing platform data fetched from the IGDB API while allowing for custom modifications, you can consider a hybrid approach that combines both API data and custom data within a single model. Here's a structured way to achieve this:

Database Structure

  1. Platforms Table: This table will store the platform data fetched from the IGDB API, along with any custom modifications.

    • id: Primary key.
    • api_id: The ID from the IGDB API.
    • name: The original name fetched from the API.
    • custom_name: A nullable field for any custom name modifications.
    • other_fields: Any other fields you might need from the API.

Model Structure

In your Platform model, you can use an accessor to determine which name to display:

class Platform extends Model
{
    protected $fillable = ['api_id', 'name', 'custom_name', 'other_fields'];

    public function getNameAttribute()
    {
        return $this->custom_name ?? $this->name;
    }
}

Workflow

  1. Fetching and Storing Data: When you fetch data from the IGDB API, store it in the Platforms table. If a platform already exists, update the existing record without overwriting the custom_name.

  2. Modifying Data: When a user modifies the platform name, update the custom_name field. This ensures that your custom modifications are preserved.

  3. Reverting Changes: To revert to the original name, simply set custom_name to null.

  4. Updating from API: When updating platforms from the IGDB API, ensure that you only update the name field if custom_name is null, preserving any custom modifications.

Example Code for Updating Platforms

Here's a simple example of how you might update platforms from the API:

public function updatePlatformsFromApi($apiPlatforms)
{
    foreach ($apiPlatforms as $apiPlatform) {
        $platform = Platform::updateOrCreate(
            ['api_id' => $apiPlatform['id']],
            ['name' => $apiPlatform['name'], 'other_fields' => $apiPlatform['other_fields']]
        );

        // Ensure custom_name is not overwritten
        if ($platform->custom_name) {
            $platform->name = $platform->custom_name;
        }

        $platform->save();
    }
}

Conclusion

This approach allows you to maintain a single source of truth for platform data while providing flexibility for custom modifications. It also simplifies the logic for displaying platform names by using an accessor in your model. This structure should serve your needs well as you continue to develop your application.

Please or to participate in this conversation.