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?
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
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.
@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
@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;
@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:
@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 😀