关于问题how can I use like query in ruby with sinatra?我有以下问题保护我的sql免于注入。这是我从类型字符串进行查询的方法,它接收av(alue)搜索和ak(ey) (=字段)查看。
之后,各种部分由selection.join(' and ')
def string_selector(k, v)
case
when v[/\|/]
v.scan(/([^\|]+)(\|)([^\|]+)/).map {|p| "lower(#{k}) LIKE '%#{p.first.downcase}%' or lower(#{k}) LIKE '%#{p.last.downcase}%'"}
when v[/[<>=]/]
v.scan(/(<=?|>=?|=)([^<>=]+)/).map { |part| p part; "#{k} #{part.first} '#{part.last.strip}'"}
else
# "lower(#{k}) LIKE '%#{v.downcase}%'" #(works)
("lower(#{k}) LIKE ?", '%#{v.downcase}%') #doesn't work
end
end
但我得到了错误
selectors.rb:38: syntax error, unexpected keyword_end, expecting $end
from C:/../1.9.1/rubygems/core_ext/kernel_require.rb:55:in `require'
我可能做错了什么?
答案 0 :(得分:1)
如果您使用ActiveRecord,必须有更好的方法来执行您要执行的操作...但是,如果您出于某种原因需要支持string_selector
功能,我至少会使用Arel :
def string_selector(k, v)
tbl = Arel::Table.new(:test) # your table, or you could pass this in...
condition = case v
when /\|/
vals = v.split(/\|/)
first = vals.shift
vals.inject(tbl[k].matches("%#{first.strip}%")) do |acc, val|
acc.or(tbl[k].matches("%#{val.strip}%"))
end
when /<>/
tbl[k].not_eq(v.gsub(/<>/, '').strip)
when /\=/
tbl[k].eq(v.gsub(/\=/, '').strip)
else
tbl[k].matches(v.strip)
end
tbl.where(condition).to_sql
end
请注意,matches
会为您执行不区分大小写的查询(例如,在PostgreSQL中使用ILIKE
)。