Ruby
Rails

Active StorageのN+1問題を解決する

はじめに

Active Storageを用いて画像を呼び出す際にN+1問題に直面したんで、解決方法を書き残しておきます。Active Storageの概要はこちらからどうぞ。

with_attached_attachment_nameを使う

Active Storageにはwith_attached_attachment_nameというスコープが存在します。
with_attached_attachment_name内ではincludes("#{name}_attachment": :blob)のように関連付けられたblobをincludeしています。以下のbookを例に見ていきましょう。

model/book.rb
class Book < ApplicationRecord
  has_one_attached :book_image
end

has_one_attachedメソッドを使ってActive Storageにbook_imageをアタッチメントしました。これによりwith_attached_book_imageというスコープが作成されます。このwith_attached_book_imageallの代わりに使用します。

allでBookを全件取得した場合

controller/book_controller.rb
class BooksController < ApplicationController
  def index
    @books = Book.all
  end

スクリーンショット 2018-07-09 16.19.25.png
案の定N+1問題があります。

with_attached_book_imageでBookを全件取得した場合

controller/book_controller.rb
class BooksController < ApplicationController
  def index
    @books = Book.with_attached_book_image
  end

スクリーンショット 2018-07-09 17.16.40.png
N+1問題が解決します。

まとめ

Active Storageを扱う際は関連付けられたblobをincludeするwith_attached_attachment_nameを使いましょう。