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.