次の変数があります。
query = "(first_name = ?) AND (country = ?)" # string
values = ['Bob', 'USA'] # array
次の結果が必要です。
result = "(first_name = Bob) AND (country = USA)" # string
置換の数はさまざまです (1..20)。
Rubyでそれを行う最良の方法は何ですか?
次の変数があります。
query = "(first_name = ?) AND (country = ?)" # string
values = ['Bob', 'USA'] # array
次の結果が必要です。
result = "(first_name = Bob) AND (country = USA)" # string
置換の数はさまざまです (1..20)。
Rubyでそれを行う最良の方法は何ですか?
配列を破棄しても構わない場合:
query.gsub('?') { values.shift }
それ以外の場合は、配列をコピーしてから置換を行います。
編集:正規表現の代わりに gsub('?') を使用。
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
。
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)"
この質問にはruby-on-rails のActiveRecord::QueryMethods#where
タグが付けられているため、Array Conditionsを使用できます (使用する必要があります) 。
ActiveRecord::PreparedStatementInvalid
で間違った数のバインド変数を指定すると、これvalues
が発生します。これにより、これを自分で確認する必要がなくなります。
Rails が置換を実行するため、これはエレガントであるだけでなく、その過程で SQL をサニタイズすることにより、SQL インジェクション攻撃から保護するのにも役立ちます。
あなたのモデルが呼び出され、あなたの質問のようにあると仮定するとUser
、query
これvalue
は次のとおりです。
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