Getting typed results from ActiveRecord raw SQL
While I have no doubt that Björn Nilsson's answer worked when he posted it, it is failing for me with Postgres 9.4
and PG gem version 0.18.2
. I have found the following to work after looking through the PG gem documentation:
pg = ActiveRecord::Base.connection
@type_map ||= PG::BasicTypeMapForResults.new(pg.raw_connection)
res = pg.execute("SELECT 'abc'::TEXT AS a, 123::INTEGER AS b, 1.23::FLOAT;")
res.type_map = @type_map
res[0]
# => {"a"=>"abc", "b"=>123, "float8"=>1.23}
Pretty ugly but does what you are asking for:
res = ActiveRecord::Base.connection.
select_all("select 1 as aa, false as aas, 123::varchar, Array[1,2] as xx")
# Breaks unless returned values have unique column names
res.map{|row|row.map{|col,val|res.column_types[col].type_cast val}}
# Don't care about no column names
res.map{|row|
row.values.map.with_index{|val,idx|
res.column_types.values[idx].type_cast val
}
}
gives:
[[1, false, "123", [1, 2]]]
How it works:
res.column_types
returns a hash of columns names and Postgresql column types
Here is a pointer to how it works: https://github.com/rails/docrails/blob/fb8ac4f7b8487e4bb5c241dc0ba74da30f21ce9f/activerecord/lib/active_record/connection_adapters/postgresql/oid/float.rb