我有一个方法,它接受一个列名并在我的模型上定义一个范围。该范围利用 PostgreSQL 窗口函数(如 rank() 和 row_number()),向结果数据集添加一个附加列。例如,User.ranked_on_score
应该添加一个rank()
别名为score_ranking
.
目前,我通过简单的字符串插值(伪代码)实现了它:
window_alias = "#{attr}_rankings"
result_alias = "#{attr}_ranking"
select("users.*, #{window_alias}.#{result_alias}")
.join("JOIN (SELECT id, rank() OVER (ORDER BY #{attr} ASC) as #{result_alias} ...")
考虑到范围应该预先定义为宏并且不接受用户输入,这种方法应该是安全的;不过,我不喜欢它。
我知道这种sanitize_sql
方法,但在我的情况下它不起作用。它将参数包装在单引号中,这在子句中很好WHERE
,但如果在子句中使用会引发语法错误SELECT
(PG 要求标识符用双引号括起来)。
是否有任何内置的标识符清理方法?还是我应该就这样离开它?