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

jimbob's avatar

Anyone had this before - polymorphic relationships

Hi All,

I am running laravel 8 using MySQL as the database. I have three tables setup in a polymorphic relationship. A row in the child table 'orders' will reference either the 'individual_orders' or 'bulk_orders' table.

This has worked fine all the way through development and into production but something weird happened yesterday that i can't track down. The user created a bulk order but when I run the following it will return the relations of every order apart from one of them.

return Order::with(['orderable'])->get();

The primary key in bulk_orders and orderable_id in 'orders' are the same so it isn't that. I can create another 'Bulk Order' and it works fine...it is just one record that won't return with the relationship.

I log the sql calls and when i pick up the one that says "select * from 'bulk_orders' where bulk_order_id in (4, 0)" and i run that on my sql console it return one of the records but not the other.

I am not sure what is happening here. Can some shed some light on something maybe happening in the background that i am unaware of?

Cheers

0 likes
9 replies
jimbob's avatar

@Snapey yeah i thought that but not sure how to fix that or whether it needs to be fixing. Is it an internal database pointer type thing?

jimbob's avatar

A bit more on this as i have been playing around.

If i call the following i get the relation return

Order::find('63185da4-409d-4557-a9f1-b7cab6174675')->orderable;

But if i call the following i don't get the relation back as part of the response

Order::with(['orderable'])->find('63185da4-409d-4557-a9f1-b7cab6174675');

Note: that if i call a a different record using the one just above it does work.

It is something to do with that record in the database....i feel like it is caching or something and have tried artisan cache:clear, artisan clear-compiled and artisan optimize but nothing seems to be working

Tippin's avatar

Are you positive all your polymorphed models all share the same primary key type, auto-incrementing | CHAR 36 UUID ? And your migrations also properly reflect that? Asking because you showed querying a UUID, then had orderable ID's as INTs.

jimbob's avatar

@Tippin Yeah i am sure of that, i have double checked them all

I use UUID for my primary keys on everything. I am not sure what is happening when laravel does

"select * from 'bulk_orders' where bulk_order_id in (4, 0)"

But i thought they are not primary keys in the brackets but either resource identifiers on the database or record numbers rather than uuid's

The fact that it works for other relationships for records in the orders & bulk_orders tables but not for one particular one in my means that it does work in general.....just something in the record itself (or cache in laravel etc) is causing the problem

Tippin's avatar
Tippin
Best Answer
Level 13

@jimbob Hmm, without being able to see more of the system, it is hard for me to guess what could cause this. The only things that stick out to me, are the (4, 0) which I have seen happen when a model using UUIDs forgets to specify $keyType = 'string'. Can you show the DB query made when you get the data you "expect"? Namely: Order::find('63185da4-409d-4557-a9f1-b7cab6174675')->orderable;

jimbob's avatar

@Tippin You Sir have cracked it. I didn't set $keyType = 'string' in the model. Once i did that it worked perfectly and even the db queries use the actual keys.

I find it weird that it was working without that and would love to know that underlying cause. I have about 30 tables in total using a mixture of normal relationships and polymorphic and this is the only record i have had a problem with....causing me to think it works without have to set keyType = 'string'

I just went back to the documentation and totally missed the section:

If your model's primary key is not an integer, you should define a protected $keyType property on your model. This property should have a value of string:

Thanks for your help Tippin!!!!!!

1 like
Tippin's avatar

@jimbob Anytime, your DB query set that red flag off right away in my head. And your "data" may have worked before, if the first key matched, since it parses as a string (but without laravel knowing, only takes the INT of the UUID, so first number basically), but you could have also been giving wrong data back as well, without knowing. Please mark as solved 😀

Snapey's avatar

no, there is no such thing as 'resource identifiers' or record numbers

If you are using uuid and not auto incrementing keys then make sure you have public $incrementing=false; in your models.

Please or to participate in this conversation.