ume

Rails7メンターさんにしていただいたこと(Active StorageのN+1問題)

前書き

現在ECサイトを作成しています。

以下のコードで上記の表示をしています.
index.html(↓わかりやすいように余計なdivタグなど省略).
products_controller.rb

class ProductsController < ApplicationController
  def index
    @products = Product.all   #productテーブルからデータを全て取得
end 

index.html.erb

<% @products.each do |product| %> #Productテーブルのデータを一つずつ取り出す(みかんなど)
<%= link_to product_path(product.id)  do %>
 <%= image_tag product.image,class:"w-100 h-100", style:" aspect-ratio: 2 / 1;"   if product.image.attached? %>#product.imageでproduct(みかんなど)の関連データ(みかんの画像など)を取得表示する
<% end %>
<% end %>

データベースには Productテーブルに商品に関するデータが入っておりblobテーブルには商品に関連のある画像が格納されている

指摘箇所

Products_controller.rb

class ProductsController < ApplicationController
私のコード↓
  def index
    @products = Product.all
  end
メンターさんに↓のように修正するようにと言われました。
  def index
    @products = Product.with_attached_image
  end
end

解説(なぜこのように修正する必要があるか)

⇨N+1問題を解決するため

N+1問題とは?

shuttodev.hatenablog.com

https://pikawaka.com/rails/includes

N+1問題を一言でいうと「無駄にSQLが発行される」状態

どういう時にN+1問題が発生する?

⇨モデルオブジェクト.関連名.

関連名とは?

models/product.rbファイル

class Product < ApplicationRecord
  has_one_attached :image #⇦ここが
関連名
end 

下のコードを実行するとN+1問題発生する

@products = Product.all
@product.each do |product|
product.image  #⇦ここで無駄なSQLが発行される
end 
 解決策(active storageを使用している場合)

⇨ with_attached_imageメソッドを使う

@products = Product. with_attached_image

まとめ

  • N+1問題とは無駄なSQLを発行してしまう問題

  • モデルオブジェクト.関連名で発生する