12
votes

ActiveRecord's .where() query method supports interpolation like this:

Book.where("author_id IS ? AND genre_id IS ?", author_id, genre_id)

Does the .select() method support similar interpolation, or would we need to use standard Ruby string interpolation (e.g. "WHEN genre_id IS #{genre_id} THEN 2").

(This might seem like a far-fetched use case, but essentially we're building a query with a calculated field - SUM() as sum for example - which uses different values depending on each record's fields, via a CASE statement, and we'd like to avoid hard-coding values into the query.)

I'm interested in all answers, but this particular application happens to still be on Rails 3.2.x.

1
I think you'll have to rely on Ruby's string interpolation. ActiveRecord's select will receive either a symbol array or a string array, but it will not replace any bind parameters in those strings. See here for the doc: api.rubyonrails.org/classes/ActiveRecord/…eugen

1 Answers

6
votes

You can use one of the ActiveRecord::Sanitization for this:

def self.select_with_params(sql, params = [])
  query = sanitize_sql_array([sql, params].flatten)
  select(query)
end

And use this method inside AR chaining:

User.where(name: 'name').select_with_params("name='%s' and group_id='%s'", "foo'bar", 4)