🐼
注文一覧(管理者側) topに表示。N+1クエリ問題
-
管理側で注文履歴一覧をtop画面で表示させる
コントローラー
admin/homescontroller
class Admin::HomesController < ApplicationController
def top
@orders = Order.includes(:customer, :order_details).order(created_at: :desc).page(params[:page]).per(10)
end
end
- 解説
@orders = Order.
@order変数にOrderモデルからデータを取得して代入
includes(:customer, :order_details)
- (:customer, :order_details)はモデルの関連づけからきてる
app/models/order.rb
class Order < ApplicationRecord
belongs_to :customer
has_many :order_details
end
-
N+1クエリ問題を避けるため(下記に詳しく)
-
order(created_at: :desc)
作成日時の降順で注文を並び替える。最新の注文が最初に表示されるようになる。どんな時も[先頭はorderでいい。]
注文履歴一覧(top)ビュー
admin/homes/top.html.erb
<div class="container">
<div class="row">
<div class="mx-auto offset-lg-2">
<h4>注文履歴一覧</h4>
<table class="table">
<thead>
<tr>
<td class="field">
<th>購入日時</th>
<th>購入者</th>
<th>注文個数</th>
<th>注文ステータス</th>
</td>
</tr>
</thead>
<tbody>
<% @orders.each do |order| %>
<tr>
<!--日時を注文履歴詳細へリンク-->
<td class="field">
<td>
<%= link_to admin_order_path(order) do %>
<%= order.created_at.strftime("%Y/%m/%d %H:%M") %>
<% end %>
</td>
<td><%= order.customer.last_name %><%= order.customer.first_name %></td>
<td><%= order.order_details.sum(:amount) %></td>
<td><%= order.order_status_i18n %></td>
</tr>
<% end %>
<td><%= paginate(@orders) %></td>
</tbody>
</table>
</div>
</div>
</div>
N+1クエリ問題とは
データベースにアクセスする時の非効率なクエリ発行によるパフォーマンス問題のこと。
関連するデータを事前ロードするメソッドとして"includes"が必要...
これを使うと、アプリケーションのレスポンス速度が向上するみたい。
N+1クエリ問題の例
orders = Order.all
orders.each do |order|
puts order.customer.name
end
1.Order.all
:全注文を取得する1回のクエリ。
2.各注文に対して、関連する顧客を取得するためのクエリ。
(10件の注文がある場合は、1と2合わせて、11回のクエリが発行。)
これが、N+1クエリ問題。
order(created_at: :desc)
作成日時の降順で注文を並び替える。最新の注文が最初に表示されるようになる。
ふーん。
Discussion