Read more

Rails: Talking to the database without instantiating ActiveRecord objects

Dominik Schöler
November 08, 2016Software engineer at makandra GmbH

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.

Illustration online protection

Rails professionals since 2007

Our laser focus on a single technology has made us a leader in this space. Need help?

  • We build a solid first version of your product
  • We train your development team
  • We rescue your project in trouble
Read more Show archive.org snapshot

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)
Posted by Dominik Schöler to makandra dev (2016-11-08 09:34)