diff --git a/plugins/poll/app/models/poll.rb b/plugins/poll/app/models/poll.rb index 44ce17f46cf..210533836ff 100644 --- a/plugins/poll/app/models/poll.rb +++ b/plugins/poll/app/models/poll.rb @@ -55,7 +55,7 @@ class Poll < ActiveRecord::Base end 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 def can_see_voters?(user) diff --git a/plugins/poll/app/serializers/poll_serializer.rb b/plugins/poll/app/serializers/poll_serializer.rb index c540d7b34b6..171eb95387f 100644 --- a/plugins/poll/app/serializers/poll_serializer.rb +++ b/plugins/poll/app/serializers/poll_serializer.rb @@ -45,7 +45,7 @@ class PollSerializer < ApplicationSerializer end 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 def close diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index 1dee522602c..391610c26f1 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -68,7 +68,7 @@ after_initialize do raise StandardError.new I18n.t("poll.user_cant_post_in_topic") 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.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) 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 PollVote .where(poll: poll, user: user) .where.not(poll_option_id: new_option_ids) .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 (new_option_ids - old_option_ids).each do |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? Poll - .includes(poll_options: :poll_votes, poll_votes: :poll_option) .where(post_id: post_with_polls) .each do |p| polls[p.post_id] ||= [] @@ -591,7 +590,7 @@ after_initialize do @preloaded_polls ||= if @topic_view.present? @topic_view.polls[object.id] else - Poll.includes(poll_options: :poll_votes).where(post: object) + Poll.includes(:poll_options).where(post: object) end end @@ -609,11 +608,12 @@ after_initialize do add_to_serializer(:post, :polls_votes, false) do preloaded_polls.map do |poll| - user_poll_votes = poll.poll_votes.each_with_object([]) do |vote, obj| - if vote.user_id == scope.user.id - obj << vote.poll_option.digest - end - end + user_poll_votes = + poll + .poll_votes + .where(user_id: scope.user.id) + .joins(:poll_option) + .pluck("poll_options.digest") [poll.name, user_poll_votes] end.to_h