HaMMerHeD's avatar

Polymorphic Target Key Type Casting

Good day.

I have a model called Message and a trait called HasMessages which, predictably enough, defines a polymorphic relationship to Message with the traited model.

Works great.

Only, since the HasMessages trait can be applied to any model in any database in my app, including (importantly) those stored in MongoDB databases, the owner_id field is necessarily a varchar field.

This worked fine when I was using mysql. However, I am migrating the database from myql to PostgreSQL, which is a bit more particular about string/integer comparisons. Specifically, as of version 8.4 (I am using version 11) it no longer does "magic" type casting during runtime, so it throws this error:

ERROR:  operator does not exist: character varying = integer
LINE 1: ...rom "Core"."messages" where "messages"."owner_id" in (2) and...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

The message model's relationship to its owner is this:

public function owner()
{
    return $this->morphTo('owner');
}

The target model's relationship to its messages (within the HasMessages trait) is this

public function messages()
{
    return $this->morphMany(Message::class, 'owner')->orderBy('created_at', 'desc');
}

The query that Eloquent generates is this:

select * from "Core"."messages" where "messages"."owner_id" in (2) and "messages"."owner_type" = 'App\Sales\Jobs\Entities\Job' and "messages"."deleted_at" is null order by "created_at" desc

(which throws the above error).

What I need it to be is this:

select * from "Core"."messages" where "messages"."owner_id" in ('2') and "messages"."owner_type" = 'App\Sales\Jobs\Entities\Job' and "messages"."deleted_at" is null order by "created_at" desc

or

select * from "Core"."messages" where "messages"."owner_id" in (2::varchar) and "messages"."owner_type" = 'App\Sales\Jobs\Entities\Job' and "messages"."deleted_at" is null order by "created_at" desc

(both of which work fine).

I.E., the foreign key 2 needs to be '2' or 2::varchar.

I have added owner_id to the protected $casts array as 'string', but the error persists. The only 'type' related options I can find on the polymorphic relationship methods seem to be related to changing the name of the {type}_id and {type}_type fields. I tried that anyway, in case my impression of that was wrong, but again the error persists.

I hope this is something stupid I have overlooked.

Any ideas?

0 likes
1 reply
makro's avatar

Hi, did you solve this?

1 like

Please or to participate in this conversation.