From 4f024d2360581b2778465ebcb49ffa4b56ee0a11 Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 8 Aug 2019 23:12:40 -0500 Subject: [PATCH] pools/show: fix N+1 query on pool show page. Fix a N+1 query when fetching posts to render thumbnails. Also adds support for the `limit` url param on the posts show page. --- app/controllers/pools_controller.rb | 2 +- app/logical/post_query_builder.rb | 1 + app/models/pool.rb | 19 ++++--------------- app/views/pools/show.html.erb | 10 ++++++++-- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/app/controllers/pools_controller.rb b/app/controllers/pools_controller.rb index 0235eca47..e569d768a 100644 --- a/app/controllers/pools_controller.rb +++ b/app/controllers/pools_controller.rb @@ -39,7 +39,7 @@ class PoolsController < ApplicationController def show @pool = Pool.find(params[:id]) - @post_set = PostSets::Pool.new(@pool, params[:page]) + @posts = @pool.posts.paginate(params[:page], limit: params[:limit], count: @pool.post_count) respond_with(@pool) end diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index f386432b9..314d5b18a 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -433,6 +433,7 @@ class PostQueryBuilder if q[:ordpool].present? pool_id = q[:ordpool].to_i + # XXX unify with Pool#posts pool_posts = Pool.joins("CROSS JOIN unnest(pools.post_ids) WITH ORDINALITY AS row(post_id, pool_index)").where(id: pool_id).select(:post_id, :pool_index) relation = relation.joins("JOIN (#{pool_posts.to_sql}) pool_posts ON pool_posts.post_id = posts.id").order("pool_posts.pool_index ASC") end diff --git a/app/models/pool.rb b/app/models/pool.rb index 35d233aa1..0ec530f48 100644 --- a/app/models/pool.rb +++ b/app/models/pool.rb @@ -213,21 +213,10 @@ class Pool < ApplicationRecord end end - def posts(options = {}) - offset = options[:offset] || 0 - limit = options[:limit] || Danbooru.config.posts_per_page - slice = post_ids.slice(offset, limit) - if slice && slice.any? - slice.map do |id| - begin - Post.find(id) - rescue ActiveRecord::RecordNotFound - # swallow - end - end.compact - else - [] - end + # XXX unify with PostQueryBuilder ordpool search + def posts + pool_posts = Pool.where(id: id).joins("CROSS JOIN unnest(pools.post_ids) WITH ORDINALITY AS row(post_id, pool_index)").select(:post_id, :pool_index) + posts = Post.joins("JOIN (#{pool_posts.to_sql}) pool_posts ON pool_posts.post_id = posts.id").order("pool_posts.pool_index ASC") end def synchronize diff --git a/app/views/pools/show.html.erb b/app/views/pools/show.html.erb index 0adcf2bf4..d3a2fe1a7 100644 --- a/app/views/pools/show.html.erb +++ b/app/views/pools/show.html.erb @@ -15,9 +15,15 @@ <%= render "posts/partials/common/inline_blacklist" %>
- <%= @post_set.presenter.post_previews_html(self) %> + <% if @pool.post_count == 0 %> + <%= render "post_sets/blank" %> + <% else %> + <% @posts.each do |post| %> + <%= PostPresenter.preview(post, pool_id: @pool.id) %> + <% end %> - <%= numbered_paginator(@post_set) %> + <%= numbered_paginator(@posts) %> + <% end %>