Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to typecast a join column in Arel

On my postgres db, I have a primary key using a UUID. Sample setup below

class Visit
 # primary key id: uuid
 has_many :connections, as: :connectable
 has_many :payments, through: :connections
end

class Connection #(polymorphic class joining visit and payment)
  # columns connectable_type(string), connectable_id(string)
  belongs_to :payments
  belongs_to :connectable, polymorphic: true
end

class Payment
  # primary key id: uuid
  has_many :connections
end

When I try to fetch all visits with payments, I got an error:

Visit.joins(:payments)
# => operator does not exist: character varying = uuid` 

Basically this requires that I explicitly cast the visit.id to varchar, which I could easily do if my join statements were a string, by:

connections.connectable_id = visits.id::varchar

however I'm using Arel for composability.

Could anyone guide as to how I can typecast this directly with Arel, so I could easily do something like:

join(connections_table).on(connections_table[:connectable_id].eq(cast_to_string(visits_table[:id]))) 
# where connections_table and visits_table are Arel tables
like image 906
oreoluwa Avatar asked Mar 03 '17 17:03

oreoluwa


1 Answers

While playing around with this, I found out about Arel NamedFunction which basically is a way to wrap your [custom] SQL functions in Arel. In this case, I ended up with:

casted_visits_primary_key = Arel::Nodes::NamedFunction.new("CAST", [ visits_table[:id].as("VARCHAR") ])

And then I was able to do:

join(connections_table).on(connections_table[:connectable_id].eq(casted_visits_primary_key))

And that basically solved my problem!

like image 169
oreoluwa Avatar answered Nov 19 '22 19:11

oreoluwa