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

Aetrox's avatar

Relations

Hello,

after the 7th time deleting my tables and models, i realize i need a bit of help getting my database structure working.

I have a User with multiple Devices.

Each Device has data like Serialnumber, purchase date and so on.

Each Device has a related table Storage, Color, Model, Manufacturer.

So what relations do i have?

User hasMany Devices

Device hasOne Color Device hasOne Storage Device hasOne Model Device hasOne Manufacturer

where do i have to set the foreignkeys now?

Do i have a table with devices with a foreignkey user_id? And do i have a table Storage with a foreignkey device_id?

I am not sure about this because after my logic i then have a table like: Storage | device_id 256 | 1 256 | 2 64 | 3

Am i on the right track or would there be a better solution?

At the end i just want to find a user and get all device-data without having to write 20 loops and 40 lines of code.

RIght now i have a many to many between user and device and in my device table i have foreignkeys for storage color model and manufacturer but if i do it like in the docs i should have the foreignkeys on the Device-Data-Tables to access them with a hasOne Relation.

I hope i didnt wrote to much senseless stuff.

I would be happy if you could help me out a little bit.

Thanks a lot.

0 likes
8 replies
martinbean's avatar

@Aetrox I’d say you have users that have many devices, and a device has many attributes. An attribute would be key–value pairs for things like colour, storage capacity etc. Serial number sounds pretty standard, so I’d be tempted to move that to the Device model.

Aetrox's avatar

@martinbean thanks for your reply,

so do i get it right that you would do the tables like this:

user hasMany devices devices hasMany attributes attributes hasOne Color attributes hasOne Manufacturer attributes hasOne Model attributes hasOne Storage

So it would look like this? Color 1 | Silver 2 | Spacegrey Model 1 | iPhone 8 2 | iPhone 7 Attributes 1 | color_id 1| model_id 2 2 | color_id 2| model_id 1 Devices: 1 | | And i have a pivot table: device_attribute: ID device_id atribute_id 1 1 2

Please correct me if i am wrong and thank you very much @martinbean

martinbean's avatar

@Aetrox No. Attributes would be key–value pairs. So attributes would have name and value columns. The name may be colour and the value red.

Aetrox's avatar

@martinbean Oh so you mean only 3 tables: User -> Devices -> Attributes

And in Attributes are the columns Storage Color Model etc. ?

Wait, no you mean a column with name and value

so name would be Color, Storage etc and the values would be red, 256 and so on.

I cant imagin how this would look like with many devices. :/ feeling a bit dumb at the moment.

So a device has many attributes like Red, iPhone, 256, Apple

But another device has Blue, S9, 64, Samsung.

Wouldnt that mean i need an attributes table for each device, or do i have multiple Color rows like:

Color:Red, Color:Blue, Color:Pink

I cant wrap my head around this.

martinbean's avatar
Level 80

@Aetrox A device would have many attributes, so that means your attributes table would have a device_id foreign key:

Schema::create('devices', function (Blueprint $table) {
    $table->increments('id');
    $table->string('serial_number')->unique();
    $table->timestamps();
});

Schema::create('attributes', function (Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('device_id');
    $table->string('name');
    $table->string('value');
    $table->timestamps();
    $table->foreign('device_id')->references('id')->on('devices')->onDelete('cascade');
    
    // Stops a single device having multiple attributes with the same name
    $table->unique(['device_id', 'name']);
});
1 like
Aetrox's avatar

@martinbean Okay now i understand. So i have for the device with the id 1

id  1 Color             Blue        timestamp
id  1 Storage       64          timestamp
id  1 Manufacturer  Apple       timestamp
id  1 Model             iPhone 8    timestamp

thank you very much

shez1983's avatar

you could further complicate (normalise it) by

    $table->increments('id');
    $table->unsignedInteger('device_id');
    $table->string('name');
    $table->string('value');
    $table->timestamps();```

could be

Schema::create('attributes', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('device_id'); $table->string('attribute_id'); $table->string('value_id'); $table->timestamps();


attribute_id = > table with id, name  e.g  1, Colour, 2 Storage, 
value_id => table with all options id, attribute_id, name:  1, 1, Blue,  2, 1, Red,  3, 2, Storage_value
Aetrox's avatar

@martinbean @shez1983

Yes i could further normalize it, But in the Lesser complicated way it is hard enough to Format the output later. I Return my Query as json, and Then have to iterate over and over to get the whole data.

I have a User loop over the devices, Loop over attributes, Loop over contracts etc.. i Hope i someday find a better way to get my Output. Thank you very much for your help @martinbean @shez1983

Please or to participate in this conversation.