Sequel 将单引号添加到 .where

Sequel adds single quotes to .where

我将 Sequel 与 Sinatra API 和 Postgres 一起使用。我有一个名为 'results':

的基本数据集
results = Receipt.order(Sequel.desc(:date))

我正在尝试使用来自 JSON 对象的散列对其进行过滤,如下所示:

filters = {item: 'mortgage',
           method: 'check'}

def get_filtered_results(results, filters)
    filters.each do |key, value|
        results = results.where('? = ?', key, value)
    end
    return results
end

由这些 '.where's 生成的 sql 查询是:

SELECT * FROM "receipts" WHERE ('item' = 'mortgage') and ('method' = 'check') ORDER BY "date" DESC LIMIT 50 OFFSET 0;

'item' 和 'method' 周围的引号导致查询没有 return 任何结果 - 当我 运行 他们手动 运行 他们 return 预期的记录。我尝试将过滤器作为散列而不是准备好的语句传递,结果相同。有什么方法可以构建不带引号的查询吗?

编辑:当我在 pry 中构建语句时 - 所以

Receipt.order(Sequel.desc(:date)).where(:item => 'mortgage payment').where(:method => 'check')

我得到了预期的结果。

问题是占位符中将被替换的值被视为字符串而不是字段名称。您必须在查询中插入散列 key。但是,这会使查询容易受到攻击,因此最好创建一个允许的过滤器数组:

filters = {item: 'mortgage',
           method: 'check'}

def get_filtered_results(results, filters)
  allowed_filters = [:item, :method]

  filters.slice(*allowed_filters).each do |key, value|
    results = results.where("#{key} = ?", value)
  end
  return results
end

slice() 方法将创建一个仅包含 allowed_filters 数组中的键的新哈希。