我正在使用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')
我得到了预期的结果。
答案 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
数组中的键。