FIX: a poll option cannot be voted more than 100% of the time

This commit is contained in:
Régis Hanol 2015-10-16 17:18:22 +02:00
parent 06b799bfbf
commit 8f2b002203
2 changed files with 38 additions and 20 deletions

View File

@ -0,0 +1,20 @@
class MergePollsVotes < ActiveRecord::Migration
def up
PostCustomField.where(name: "polls").order(:post_id).pluck(:post_id).each do |post_id|
polls_votes = {}
PostCustomField.where(post_id: post_id).where("name LIKE 'polls-votes-%'").find_each do |pcf|
user_id = pcf.name["polls-votes-".size..-1]
polls_votes["#{user_id}"] = ::JSON.parse(pcf.value)
end
pcf = PostCustomField.find_or_create_by(name: "polls-votes", post_id: post_id)
pcf.value = ::JSON.parse(pcf.value).merge(polls_votes).to_json
pcf.save
end
end
def down
end
end

View File

@ -66,21 +66,18 @@ after_initialize do
raise StandardError.new I18n.t("poll.requires_at_least_1_valid_option") if options.empty?
votes = post.custom_fields["#{VOTES_CUSTOM_FIELD}-#{user_id}"] || {}
vote = votes[poll_name] || []
post.custom_fields[VOTES_CUSTOM_FIELD] ||= {}
post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"] ||= {}
post.custom_fields[VOTES_CUSTOM_FIELD]["#{user_id}"][poll_name] = options
# increment counters only when the user hasn't casted a vote yet
poll["voters"] += 1 if vote.size == 0
votes = post.custom_fields[VOTES_CUSTOM_FIELD]
poll["voters"] = votes.values.count { |v| v.has_key?(poll_name) }
poll["options"].each do |option|
option["votes"] -= 1 if vote.include?(option["id"])
option["votes"] += 1 if options.include?(option["id"])
end
votes[poll_name] = options
all_options = Hash.new(0)
votes.map { |_, v| v[poll_name] }.flatten.each { |o| all_options[o] += 1 }
poll["options"].each { |option| option["votes"] = all_options[option["id"]] }
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
post.custom_fields["#{VOTES_CUSTOM_FIELD}-#{user_id}"] = votes
post.save_custom_fields(true)
MessageBus.publish("/polls/#{post_id}", { polls: polls })
@ -325,9 +322,7 @@ after_initialize do
# when the # of options has changed, reset all the votes
if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size
PostCustomField.where(post_id: post.id)
.where("name LIKE '#{VOTES_CUSTOM_FIELD}-%'")
.destroy_all
PostCustomField.where(post_id: post.id, name: VOTES_CUSTOM_FIELD).destroy_all
post.clear_custom_fields
next
end
@ -354,12 +349,10 @@ after_initialize do
end
Post.register_custom_field_type(POLLS_CUSTOM_FIELD, :json)
Post.register_custom_field_type("#{VOTES_CUSTOM_FIELD}-*", :json)
Post.register_custom_field_type(VOTES_CUSTOM_FIELD, :json)
TopicView.add_post_custom_fields_whitelister do |user|
whitelisted = [POLLS_CUSTOM_FIELD]
whitelisted << "#{VOTES_CUSTOM_FIELD}-#{user.id}" if user
whitelisted
user ? [POLLS_CUSTOM_FIELD, VOTES_CUSTOM_FIELD] : [POLLS_CUSTOM_FIELD]
end
# tells the front-end we have a poll for that post
@ -371,6 +364,11 @@ after_initialize do
add_to_serializer(:post, :polls, false) { post_custom_fields[POLLS_CUSTOM_FIELD] }
add_to_serializer(:post, :include_polls?) { post_custom_fields.present? && post_custom_fields[POLLS_CUSTOM_FIELD].present? }
add_to_serializer(:post, :polls_votes, false) { post_custom_fields["#{VOTES_CUSTOM_FIELD}-#{scope.user.id}"] }
add_to_serializer(:post, :include_polls_votes?) { scope.user && post_custom_fields.present? && post_custom_fields["#{VOTES_CUSTOM_FIELD}-#{scope.user.id}"].present? }
add_to_serializer(:post, :polls_votes, false) { post_custom_fields[VOTES_CUSTOM_FIELD]["#{scope.user.id}"] }
add_to_serializer(:post, :include_polls_votes?) do
return unless scope.user
return unless post_custom_fields.present?
return unless post_custom_fields[VOTES_CUSTOM_FIELD].present?
post_custom_fields[VOTES_CUSTOM_FIELD].has_key?("#{scope.user.id}")
end
end