modqueue: avoid N+1 queries for disapprovals, uploaders.

Fixes an N+1 queries problem in the /moderator/post/queue view by
prefetching disapprovals and uploaders.

Also the way disapproval messages were previously rendered triggered a bunch
of sql queries for each post:

    SELECT COUNT(*) FROM "post_disapprovals" WHERE "post_disapprovals"."post_id" = $1 [["post_id", 52]]
    SELECT COUNT(*) FROM "post_disapprovals" WHERE "post_disapprovals"."post_id" = $1 AND "post_disapprovals"."reason" = $2  [["post_id", 52], ["reason", "breaks_rules"]]
    SELECT COUNT(*) FROM "post_disapprovals" WHERE "post_disapprovals"."post_id" = $1 AND "post_disapprovals"."reason" = $2  [["post_id", 52], ["reason", "poor_quality"]]
    SELECT COUNT(*) FROM "post_disapprovals" WHERE "post_disapprovals"."post_id" = $1 AND "post_disapprovals"."reason" IN ('disinterest', 'legacy')  [["post_id", 52]]
    SELECT COUNT(*) FROM "post_disapprovals" WHERE "post_disapprovals"."post_id" = $1 AND (message is not null and message <> '')  [["post_id", 52]]
    SELECT "post_disapprovals".* FROM "post_disapprovals" WHERE "post_disapprovals"."post_id" = $1 AND (message is not null and message <> '')  [["post_id", 52]]

This refactors to bring it down to one:

    SELECT "post_disapprovals".* FROM "post_disapprovals" WHERE "post_disapprovals"."post_id" = $1  [["post_id", 52]]
This commit is contained in:
evazion
2017-02-24 19:13:02 -06:00
parent 9b40016895
commit 83915a5d46
3 changed files with 19 additions and 19 deletions

View File

@@ -15,7 +15,7 @@ module Moderator
end
::Post.without_timeout do
@posts = ::Post.order("posts.id asc").pending_or_flagged.available_for_moderation(params[:hidden]).tag_match(params[:query]).paginate(params[:page], :limit => per_page)
@posts = ::Post.includes(:disapprovals, :uploader).order("posts.id asc").pending_or_flagged.available_for_moderation(params[:hidden]).tag_match(params[:query]).paginate(params[:page], :limit => per_page)
@posts.each # hack to force rails to eager load
end
respond_with(@posts)
@@ -25,7 +25,7 @@ module Moderator
cookies.permanent[:moderated] = Time.now.to_i
::Post.without_timeout do
@posts = ::Post.order("posts.id asc").pending_or_flagged.available_for_moderation(false).reorder("random()").limit(RANDOM_COUNT)
@posts = ::Post.includes(:disapprovals, :uploader).order("posts.id asc").pending_or_flagged.available_for_moderation(false).reorder("random()").limit(RANDOM_COUNT)
@posts.each # hack to force rails to eager load
if @posts.empty?

View File

@@ -1,17 +1,17 @@
<% if disapprovals.count > 0 && (CurrentUser.can_approve_posts? || post.created_at < 3.days.ago) %>
<% if disapprovals.breaks_rules.count > 0 %>
(breaks rules: <%= disapprovals.breaks_rules.count %>)
<% if CurrentUser.can_approve_posts? || post.created_at < 3.days.ago %>
<% if disapprovals.map(&:reason).grep("breaks_rules").count > 0 %>
(breaks rules: <%= disapprovals.map(&:reason).grep("breaks_rules").count %>)
<% end %>
<% if disapprovals.poor_quality.count > 0 %>
(poor quality: <%= disapprovals.poor_quality.count %>)
<% if disapprovals.map(&:reason).grep("poor_quality").count > 0 %>
(poor quality: <%= disapprovals.map(&:reason).grep("poor_quality").count %>)
<% end %>
<% if disapprovals.disinterest.count > 0 %>
(no interest: <%= disapprovals.disinterest.count %>)
<% if disapprovals.map(&:reason).grep(/disinterest|legacy/).count > 0 %>
(no interest: <%= disapprovals.map(&:reason).grep(/disinterest|legacy/).count %>)
<% end %>
<% if disapprovals.with_message.any? %>
<% if disapprovals.map(&:message).any?(&:present?) %>
(messages: <%= disapprovals.map(&:message).select(&:present?).map { |msg| format_text(msg, ragel: true, inline: true) }.to_sentence.html_safe %>)
<% end %>
<% end %>

View File

@@ -1,20 +1,20 @@
<% if disapprovals.count > 0 && (CurrentUser.can_approve_posts? || post.created_at < 3.days.ago) %>
<% if CurrentUser.can_approve_posts? || post.created_at < 3.days.ago %>
<p>
It has been reviewed by <%= pluralize disapprovals.count, "moderator" %>.
It has been reviewed by <%= pluralize disapprovals.length, "moderator" %>.
<% if disapprovals.breaks_rules.count > 0 %>
<%= disapprovals.breaks_rules.count %> believe it breaks the rules.
<% if disapprovals.map(&:reason).grep("breaks_rules").count > 0 %>
<%= disapprovals.map(&:reason).grep("breaks_rules").count %> believe it breaks the rules.
<% end %>
<% if disapprovals.poor_quality.count > 0 %>
<%= disapprovals.poor_quality.count %> believe it has poor quality.
<% if disapprovals.map(&:reason).grep("poor_quality").count > 0 %>
<%= disapprovals.map(&:reason).grep("poor_quality").count %> believe it has poor quality.
<% end %>
<% if disapprovals.disinterest.count > 0 %>
<%= disapprovals.disinterest.count %> did not like the post enough to approve it.
<% if disapprovals.map(&:reason).grep(/disinterest|legacy/).count > 0 %>
<%= disapprovals.map(&:reason).grep(/disinterest|legacy/).count %> did not like the post enough to approve it.
<% end %>
<% if disapprovals.with_message.any? %>
<% if disapprovals.map(&:message).any?(&:present?) %>
Messages: <%= disapprovals.map(&:message).select(&:present?).map { |msg| format_text(msg, ragel: true, inline: true) }.to_sentence.html_safe %>.
<% end %>
</p>