mirror of
https://github.com/discourse/discourse.git
synced 2025-02-20 06:04:17 +08:00
PERF: Don't load all poll_votes for a poll
This commit is contained in:
parent
13c9d7e704
commit
f2842490d3
|
@ -55,7 +55,7 @@ class Poll < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_voted?(user)
|
def has_voted?(user)
|
||||||
user&.id && poll_votes.any? { |v| v.user_id == user.id }
|
user&.id && poll_votes.where(user_id: user.id).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_see_voters?(user)
|
def can_see_voters?(user)
|
||||||
|
|
|
@ -45,7 +45,7 @@ class PollSerializer < ApplicationSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def voters
|
def voters
|
||||||
object.poll_votes.map { |v| v.user_id }.uniq.count + object.anonymous_voters.to_i
|
object.poll_votes.count('DISTINCT user_id') + object.anonymous_voters.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
|
|
|
@ -68,7 +68,7 @@ after_initialize do
|
||||||
raise StandardError.new I18n.t("poll.user_cant_post_in_topic")
|
raise StandardError.new I18n.t("poll.user_cant_post_in_topic")
|
||||||
end
|
end
|
||||||
|
|
||||||
poll = Poll.includes(poll_options: :poll_votes).find_by(post_id: post_id, name: poll_name)
|
poll = Poll.includes(:poll_options).find_by(post_id: post_id, name: poll_name)
|
||||||
|
|
||||||
raise StandardError.new I18n.t("poll.no_poll_with_this_name", name: poll_name) unless poll
|
raise StandardError.new I18n.t("poll.no_poll_with_this_name", name: poll_name) unless poll
|
||||||
raise StandardError.new I18n.t("poll.poll_must_be_open_to_vote") if poll.is_closed?
|
raise StandardError.new I18n.t("poll.poll_must_be_open_to_vote") if poll.is_closed?
|
||||||
|
@ -91,18 +91,18 @@ after_initialize do
|
||||||
obj << option.id if options.include?(option.digest)
|
obj << option.id if options.include?(option.digest)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
old_option_ids = poll.poll_options.each_with_object([]) do |option, obj|
|
||||||
|
if option.poll_votes.where(user_id: user.id).exists?
|
||||||
|
obj << option.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# remove non-selected votes
|
# remove non-selected votes
|
||||||
PollVote
|
PollVote
|
||||||
.where(poll: poll, user: user)
|
.where(poll: poll, user: user)
|
||||||
.where.not(poll_option_id: new_option_ids)
|
.where.not(poll_option_id: new_option_ids)
|
||||||
.delete_all
|
.delete_all
|
||||||
|
|
||||||
old_option_ids = poll.poll_options.each_with_object([]) do |option, obj|
|
|
||||||
if option.poll_votes.any? { |v| v.user_id == user.id }
|
|
||||||
obj << option.id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# create missing votes
|
# create missing votes
|
||||||
(new_option_ids - old_option_ids).each do |option_id|
|
(new_option_ids - old_option_ids).each do |option_id|
|
||||||
PollVote.create!(poll: poll, user: user, poll_option_id: option_id)
|
PollVote.create!(poll: poll, user: user, poll_option_id: option_id)
|
||||||
|
@ -575,7 +575,6 @@ after_initialize do
|
||||||
|
|
||||||
if post_with_polls.present?
|
if post_with_polls.present?
|
||||||
Poll
|
Poll
|
||||||
.includes(poll_options: :poll_votes, poll_votes: :poll_option)
|
|
||||||
.where(post_id: post_with_polls)
|
.where(post_id: post_with_polls)
|
||||||
.each do |p|
|
.each do |p|
|
||||||
polls[p.post_id] ||= []
|
polls[p.post_id] ||= []
|
||||||
|
@ -591,7 +590,7 @@ after_initialize do
|
||||||
@preloaded_polls ||= if @topic_view.present?
|
@preloaded_polls ||= if @topic_view.present?
|
||||||
@topic_view.polls[object.id]
|
@topic_view.polls[object.id]
|
||||||
else
|
else
|
||||||
Poll.includes(poll_options: :poll_votes).where(post: object)
|
Poll.includes(:poll_options).where(post: object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -609,11 +608,12 @@ after_initialize do
|
||||||
|
|
||||||
add_to_serializer(:post, :polls_votes, false) do
|
add_to_serializer(:post, :polls_votes, false) do
|
||||||
preloaded_polls.map do |poll|
|
preloaded_polls.map do |poll|
|
||||||
user_poll_votes = poll.poll_votes.each_with_object([]) do |vote, obj|
|
user_poll_votes =
|
||||||
if vote.user_id == scope.user.id
|
poll
|
||||||
obj << vote.poll_option.digest
|
.poll_votes
|
||||||
end
|
.where(user_id: scope.user.id)
|
||||||
end
|
.joins(:poll_option)
|
||||||
|
.pluck("poll_options.digest")
|
||||||
|
|
||||||
[poll.name, user_poll_votes]
|
[poll.name, user_poll_votes]
|
||||||
end.to_h
|
end.to_h
|
||||||
|
|
Loading…
Reference in New Issue
Block a user