假设我有一个查询:
Foo.where("lower(bar) LIKE ?", "%#{baz}%")
转换为普通SQL:
... WHERE (lower(bar) LIKE ...
,效果很好。但是我不想传递bar
来传递参数。所以我试图这样重写它:
Foo.where("lower(?) LIKE ?", bar, "%#{baz}%")
其中bar
是包含字符串'bar'
的变量。在这种情况下,它将停止工作并转换为普通SQL,如下所示:
... WHERE (lower('bar') LIKE ...
那么如何使该查询起作用?
答案 0 :(得分:2)
您可以通过Arel构建查询:
bar = :field_name # or 'string_name'.to_sym
Foo.where(Foo.arel_table[bar].lower.matches("%#{baz}%"))
答案 1 :(得分:1)
您可能要尝试在模板中使用sprintf样式的%转义符,以避免引用要插入的列名:
Foo.where("lower(%s) LIKE '%s'", bar, "%#{baz}%")
(N.B。第二个%s
周围的单引号-第二个参数确实要用引号引起来)
最后,您可以在模板中使用sprintf样式的%转义符。这与以前的方法略有不同。您有责任确保正确引用模板中的值。这些值将传递到连接器以进行引用,但是调用者负责确保将它们包含在结果SQL中的引号中。引用后,使用与Ruby核心方法Kernel :: sprintf相同的转义符插入值。