I'm using Postgres with Rails. There's a query with a subselect which returns a boolean, but Postgres always returns a String like 't'
or 'f'
. But in the generated JSON I need a real boolean.
This is my query:
SELECT
*,
EXISTS (
SELECT TRUE
FROM measurement
JOIN experiment ON measurement.experiment_id = experiment.id
JOIN location ON experiment.location_id = location.id
WHERE location.map_id = map.id
LIMIT 1
) AS measurements_exist
FROM "map"
It doesn't matter whether I use THEN true
or THEN 1
or THEN 'true'
, I will always get a string. So my JSON response will always look like that:
[
{"id":8, ..., "measurements_exist":"f"},
{"id":9, ..., "measurements_exist":"t"}
]
But it should(!) look like that:
[
{"id":8, ..., "measurements_exist":false},
{"id":9, ..., "measurements_exist":true}
]
Is there any way to get this working right?
Thank you!
THE SOLUTION:
Just give the corresponding model (here: Map
) an attribute accessor, which uses value_as_boolean
to convert the value. So every time the controller tries to access the value, it uses the attribute accessor method automatically.
The controller code:
class MapsController < ApplicationController
def index
select = ["*"]
select.push(measurements_exist) # This will just insert the string returned by the 'measurements_exist' method
maps = Map.select(select) # Results in 'SELECT *, EXISTS (...) AS measurements_exist FROM "map"'
render json: maps
end
private
def measurements_exist
"EXISTS (
SELECT TRUE
FROM measurement
JOIN experiment ON measurement.experiment_id = experiment.id
JOIN location ON experiment.location_id = location.id
WHERE location.map_id = map.id
LIMIT 1
) AS measurements_exist"
end
end
The model code:
class Map < ActiveRecord::Base
def measurements_exist
ActiveRecord::ConnectionAdapters::Column.value_to_boolean(self[:measurements_exist])
end
end
Resulting JSON:
[
{"id":7, ..., "measurements_exist":false},
{"id":6, ..., "measurements_exist":true}
]