Rails: Talking to the database without instantiating ActiveRecord objects

Updated . Posted . Visible to the public. Repeats.

Instantiating ActiveRecord objects comes expensive. To speed up things, you can choose a more direct way to talk to your database: the ActiveRecord::ConnectionAdapters::DatabaseStatements Show archive.org snapshot module.

Using the module and its methods is not suggested in the usual in-app workflow, as validations, callbacks, custom getters/setters etc. are ignored. However, for database-centered stuff like migrations, these fill the gap between writing pure SQL and full ActiveRecord. Hence, the module is included in migrations by default (also see How to write complex migrations in Rails).

Handy methods

Note that both keys and values are always strings, i.e. you'll need to typecast ids with #to_i before comparing them to usual integer ids.

select_all

Returns an ActiveRecord::Result. This object holds lots of meta info, but can be used as if it were an array of hashes. You may call #to_hash or #to_a on the result, which both will return a real Array containing real Hashes. Keys and values are always strings!

select_all('SELECT * FROM users').to_a

[
      { 'id' => '3', 'name' => 'Charlotte' },
      { 'id' => '5', 'name' => 'Ludivico' },
      ...
]

select_one

Similar to select_all, but returns a single real Hash. Keys and values are always strings!

select_values

Returns an array of the first column in a select (as strings).

select_values('SELECT id, name FROM users')
# [ '3', '5', ... ]

select_value

Same as select_values, but returns a single value as string.

There are a few more which you find in the attached link.

Usage in a model

The functions are available in migrations. If you want to use them in a model for example, you have to use the connection:

connection = ActiveRecord::Base.connection
sql = ... # your SQL Statement
results = connection.select_values(sql)
Dominik Schöler
Last edit
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted by Dominik Schöler to makandra dev (2016-11-08 08:34)