Polymorphic Association On UUID and Integer Fields Polymorphic Association On UUID and Integer Fields ruby-on-rails ruby-on-rails

Polymorphic Association On UUID and Integer Fields


This is an old question, but here's my recommendation.

This is more of an architecture problem. Don't combine UUID ids and integer ids, it get's messy real fast. If you can, migrate the integer IDs to UUID or revert the uuids to integer ids.

My experience has been that the best solution is probably to make use of the rather nice Friendly ID gem: https://github.com/norman/friendly_id

In the off case this is broken in the future, it is basically just a slug generation/managemnet tool, the slug would use this kind of route path: posts/this-is-a-potential-slug instead of posts/1, but nothing prevents you from using posts/<UUID here> or posts/<alphanumeric string here>.

Typically if you are using UUIDs it's because you don't want to show the sequential integers. Friendly ID works well to avoid that issue.


There's no means to specify the necessary cast using Rails. Instead, add a generated column with the cast, and declare an extra belongs_to association to use it. For example, with this in a migration:

add_column :interests, :_id_s, 'TEXT GENERATED ALWAYS AS (id::text) STORED'add_index :interests, :_id_s

and this in your models:

class Like  belongs_to :_likeable_cast, polymorphic: true, primary_key: :_id_s, foreign_key: :likeable_id, foreign_type: :likeable_typeclass User  has_many :interests, through: :likes, source: :_likeable_cast, source_type: "Interest"

then user.interests joins through the alternative association, i.e. using the generated column with the cast.

I suggest using a column type of text rather than varchar for the likeable_id column, to avoid unnecessary conversions during the join and ensure the index is used.


Can you describe your likes table? I suppose that it contains

  • user_id as integer,
  • likeable_id as integer,
  • likeable_type as integer
  • any third-part fields

So, technically you can not create the same polymorphic association with uuid string and id as integer in scope of two fields likeable_id and likeable_type.

As solution - you can simply add id as primary key to posts table instead of uuid. In case if you maybe do not want to show id of post in URL, or for another security reasons - you can still use uuid as before.