在我的模型中,我做了这个自定义的SQL查询:
SELECT
training_courses.id,
training_courses.training_id,
training_courses.course_id,
training_courses.is_pre_test,
training_courses.order_by,
training_course_histories.id AS training_course_history_id,
training_course_histories.finished_at,
training_course_histories.score,
CAST(coalesce(user_training_courses.id, 0) as BOOLEAN) as purchased
FROM
training_courses
LEFT OUTER JOIN training_course_histories
ON training_course_histories.training_course_id = training_courses.id AND training_course_histories.id = (
SELECT th1.id
FROM training_course_histories th1
WHERE th1.training_course_id = training_courses.id
AND th1.finished_at IS NOT NULL
AND th1.user_id = 1
ORDER BY th1.finished_at DESC LIMIT 1
)
LEFT OUTER JOIN user_training_courses
ON user_training_courses.training_course_id = training_courses.id AND user_training_courses.id = (
SELECT th2.id
FROM user_training_courses th2
WHERE th2.training_course_id = training_courses.id
AND th2.user_id = 1
)
WHERE (training_courses.training_id = 1)
GROUP BY
training_courses.id,
training_courses.id,
training_courses.training_id,
training_courses.course_id,
training_courses.is_pre_test,
training_courses.order_by,
training_course_histories.id,
training_course_histories.finished_at,
training_course_histories.score,
user_training_courses.id
ORDER BY
order_by ASC,
id ASC,
training_courses.order_by ASC,
training_courses.id ASC
以前,我使用的是Mysql数据库,所以没问题,查询就像:ISNULL(user_training_courses.id) as purchased
但现在,我正在使用Postgres,我必须拥有CAST(coalesce(user_training_courses.id, 0) as BOOLEAN) as purchased
问题:对于Rails,购买='t'或'f'(字符串)
我想要的:购买=真或假(布尔)
有可能吗?
THX。
答案 0 :(得分:1)
最后,我宁愿在我的模型中使用一个访问器来处理这种情况。
def purchased
![false, 'false', 'f', 'FALSE', 'F', 0, '0'].include?(self[:purchased])
end
答案 1 :(得分:0)
Rails PostgreSQL驱动程序理解PostgreSQL布尔值是't'
和'f'
,通常可以正确翻译它们。您的CAST:
CAST(coalesce(user_training_courses.id, 0) as BOOLEAN)
也应该没问题:
psql=> select cast(11 as boolean), cast(1 as boolean), cast(0 as boolean);
bool | bool | bool
------+------+------
t | t | f
所以我猜Rails只是不知道你的CAST的列类型。例如:
rails > ActiveRecord::Base.connection.select_rows('select cast(1 as boolean), 11 = 11')
=> [["t", "t"]]
您可以使用't'
中的设置常量将'f'
和ActiveRecord::ConnectionAdapters::Column
转换为布尔值:
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
或者您可以使用ActiveRecord::ConnectionAdapters::Column.value_to_boolean
:
rails > ActiveRecord::Base.connection.select_rows('select cast(1 as boolean), 11 = 11').map { |r| r.map { |b| ActiveRecord::ConnectionAdapters::Column.value_to_boolean(b) } }
=> [[true, true]]
但是如果您要使用低级SQL接口,您仍然需要知道所有列的类型并手动排序。类似的问题适用于整数,日期以及您获得的任何其他非字符串类型。