4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TechBlogまとめ「Active Recordのクエリ発行タイミングについて」

Posted at

SmartHRさんのTechBlogを読んで学びになったので、思考の整理のためにまとめました。

今回読んだTechBlogがこちらです。

クエリが発行されるタイミングについて

Active Recordは、そのデータが本当に必要になったときにはじめてクエリを発行するようになっている(遅延実行)。

以下のようなクエリは発行しない。

class UsersController < ApplicationController
  def index
    @users = User.where(status: 'active')
  end
end

ビューでインスタンス変数を評価するタイミングでクエリが発行される。

<% @users.each do |user| %> # ここでクエリが発行される!
  <%= user.name %>
<% end %>
クエリを発行するタイミング メソッド
即時実行 find, find_by, take, first, last, exists? すぐにクエリを発行し、データベースにアクセスし、レコード(Modelのインスタンス or インスタンスの配列)を返す。
遅延実行 上記以外のメソッド(where,order,selectなど) ActiveRecord::Relationのオブジェクトを返し、実際にデータが必要になるタイミングまでデータベースにはアクセスしない。

console環境では、遅延実行するメソッドでもクエリを発行します。これは戻り値をレシーバとしてinspectメソッドを実行し、得られた文字列を表示する仕様があるため。(自分はconsole環境で本来遅延実行するはずのメソッドを実行しても、クエリが発行されて混乱していたので、腑に落ちました。)

ActiveRecord::Relationのオブジェクトとは?
クエリを生成するための情報を保持し、メソッドチェーンでつなげることができるため、再利用性が高く、便利なものになっている。
一方でActive Recordのオブジェクトはそれなりに大きいので、たくさん作るとメモリを大量に消費するので、クエリの内容や発行回数だけでなく、オブジェクトそのものの生成も抑える必要がある。

クエリ発行タイミングの具体例

データの取得

users = User.where(name: 'John')  # ここではクエリは発行されない
users.first                       # ここでクエリが発行される

配列への置換

users = User.where(name: 'John')  # ここではクエリは発行されない
users_array = users.to_a          # ここでクエリが発行される

レコードのループ処理

users = User.where(name: 'John')  # ここではクエリは発行されない
users.each { |user| puts user.name } # ここでクエリが発行される

レコードの存在チェック

User.exists?(name: 'John')  # ここでクエリが発行される

関連データの取得

user = User.first          # ここでクエリが発行される
posts = user.posts         # もしキャッシュされていなければ、ここで再度クエリが発行される

集計メソッド

User.count                  # ここでクエリが発行される
User.average(:age)          # ここでクエリが発行される

バッチ処理

User.find_each(batch_size: 1000) { |user| ... }  # ここでクエリが発行される(バッチサイズごとに)
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?