Given a query object (not an AR model)
class ComplexQuery
QUERY = <<-SQL
...
SQL
def new(param1, param2)
...
end
def execute
# format and interpolate parameters into QUERY
# pass finished SQL to `execute` or `select_all`
end
end
How can I conveniently escape all parameters?
I've succeeded with three techniques, but none are convenient.
- Use the
raw_connectionwhich (for me) returns an instance ofPG::Connand callexec_params. I am not satisfied with this becauseexec_paramsrequires a verbose set of arguments for specifying data types. include ActiveRecord::Sanitizationin my query object and use one of its convenient methods, likereplace_named_bind_variables. I am not satisfied with this becausereplace_named_bind_variablesisprotectedand I have to usesend.- Write a
moduleinstead. For some reason, when Iinclude ActiveRecord::Sanitizationinto a module, I'm able to use its protected methods. I'm not satisfied with this because I want to instantiate my query object sometimes without executing it, e.g. for testing.
Including ActiveRecord::Sanitization into a class feels like the best solution, but I must be doing something wrong because I should be able to use a protected method.
I'm looking for a solution that:
- escapes multiple parameters
- is intended to be used by consumers of ActiveRecord
- infers the data type of a parameter and formats it accordingly
I was able to find some related questions
- Escaping values in Rails (similar to mysql_real_escape_string()) discusses escaping a single value, or suggest
sending to private methods. - Another question (ActiveRecord Select with Parameter Binding) shows how to use
sanitize_sql_arrayin a subclass of ActiveRecord::Base, but my question here is about a separate query object, not an AR model. - How to execute a raw update sql with dynamic binding in rails