续集为.where添加了单引号

时间:2015-03-22 19:26:36

标签: ruby postgresql sequel

我正在使用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

这些'生成的sql查询是:

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

围绕'项目'的引用和'方法'导致查询不返回任何结果 - 当我手动运行它们而没有引号它们返回预期的记录。我尝试将过滤器作为哈希而不是准备好的语句传递,结果相同。有没有办法在没有引号的情况下构造查询?

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

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

我得到了预期的结果。

1 个答案:

答案 0 :(得分:0)

问题是占位符中将替换的值被视为字符串而不是字段名称。您必须在查询中插入哈希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()方法将创建一个新的Hash,其中只包含allowed_filters数组中的键。