Escape parameters in a query object, using ActiveRecord?
The best way is probably to create a prepared statement using the raw Postgres driver. Unfortunately, ActiveRecord does not expose a way do do this generically. They may add it soon now that mysql2 supports prepared statements. But in the meantime, here's how to do it with the raw PG
driver in rails.
http://deveiate.org/code/pg/PG/Connection.html#method-i-prepare
conn = ActiveRecord::Base.connection.raw_connection
conn.prepare('my_query', 'SELECT foo FROM bar WHERE baz=$1 OR baz=$2')
result = conn.exec_prepared('my_query', ['param1', 'param2'])
Note the use of $
as the symbol to indicate a positional parameter. The numbers correspond to the parameter's position in the array you pass to exec_prepared
.
All the sanitization methods are already included in ActiveRecord::Base
as class methods and supposed to be run as ActiveRecord::Base#sanitize_***
.
The reason is that all sanitize_*
functions are driver-specific and rely on connection
object, which is apparently coming from ActiveRecord::ConnectionHandling
.
The ActiveSupport::Concern
contract forces Sanitization::ClassMethods
module content to become class methods of the class/module that includes Sanitization
, that is how they become available inside open ActiveRecord::Base
derived class. They are not made public [IMHO] because they require the connection established, which is usually true for descendants and might be not a case for the ActiveRecord::Base
itself.
Generally speaking, there is no unambiguous way to do what is asked without the connection (e. g. not in ActiveRecord::Base
descendant.) Quoting for postgres differs from the one for mysql.
The summing up: including ActiveRecord::Sanitization
into a class/module makes not much sense, since the whole functionality is already presented in ActiveRecord::Base
. As soon, as one wants to use these quoting functionality without actual connection behind, she is probably to implement her own quoting functions, mapping to respective ConnectionAdapter#quote
.
For the case when the connection is supposed to be established, I would go with prepending a wrapper module to ActiveRecord::Base
that would wrap protected functions to public (in this module protected functions will be available.)
Hope this helps.