用Ruby代替'?'的最优雅方式是什么?在字符串中包含数组中的值

时间:2013-07-08 10:06:36

标签: sql ruby-on-rails ruby string

我有以下变量:

query = "(first_name = ?) AND (country = ?)" # string
values = ['Bob', 'USA'] # array

我需要以下结果:

result = "(first_name = Bob) AND (country = USA)" # string

替换次数各不相同(1..20)。

在Ruby中执行此操作的最佳方法是什么?

5 个答案:

答案 0 :(得分:3)

如果你不介意破坏阵列:

query.gsub('?') { values.shift }

否则只需复制数组然后进行替换。

已编辑:使用gsub('?')代替正则表达式。

答案 1 :(得分:2)

如果您可以控制query字符串,则String#%运算符就是您所需要的:

query = "(first_name = %s) AND (country = %s)" # string
values = ['Bob', 'USA'] # array
result = query % values
#=> "(first_name = Bob) AND (country = USA)"

您必须在?字符串中将%s替换为query

答案 2 :(得分:1)

query = "(first_name = ?) AND (country = ?)"
values = ['Bob', 'USA']
result = query.dup
values.each{|s| result.sub!("?",s) }
p query
# >> "(first_name = Bob) AND (country = USA)"

答案 3 :(得分:1)

values.inject(query){|s1, s2| s1.sub("?", s2)}

答案 4 :(得分:0)

由于此问题已标记为,因此您可以(应该)将ActiveRecord::QueryMethods#whereArray Conditions一起使用。

如果您在values中提供错误数量的绑定变量,则会引发ActiveRecord::PreparedStatementInvalid,这样您就无法自行检查。

这不仅是优雅的,因为Rails会为您执行替换,它还可以通过在此过程中清理SQL来帮助您防范SQL injection attacks

实施例

假设您的模型被调用User并且queryvalue与您的问题相同,那么:

User.where(query, *values)

...将生成SQL,如:

SELECT * FROM users WHERE first_name = 'Bob' AND country = 'USA';

仅显示

上面的示例将执行查询。要在不执行的情况下显示生成的SQL,只需调用ActiveRecord::Relation#to_sql

User.where(query, *values).to_sql