3.7 応用
トランザクションを利用する
ActiveRecordのトランザクションは下記のように書くことができます。
ActiveRecord::Base.transaction do
# 例外が起こりうる処理
end
# 異常なく動作した場合の処理
rescue => e
# 例外が起こった場合の処理
N+1問題を解決する
N+1クエリ問題とは関連のモデルを取得する際に無駄にクエリを発行してしまう問題です。
例えば投稿(Post)からカテゴリ(Category)を取得する例を考えてみます。
posts = Post.limit(100)
posts.each do |post|
p post.category.name
end
このコードでは、Postを100件検索した後、そのそれぞれのに対してCategoryを取得するクエリを発行しています。検索したPostの個数をN個とすると合計101(N+1)回、クエリを発行したことになります。
Active Recordは、includes
メソッドを使って事前に読み込むモデルを指定することができます。includes
を指定すると、Active Recordは最小限のクエリ回数で読み込まれるようにしてくれます。
これを使って上のコードを書き直すと
posts = Post.includes(:category).limit(100)
posts.each do |post|
p post.category.name
end
これにより、発行したクエリの数は2回になります。