Add task to delete duplicate voters
Note that, since poll answers belong to a user and not to a voter, we aren't doing anything regarding poll answers. This is a separate topic that might be dealt with in a separate pull request. Also note that, since there are no records belonging to poll voters, and poll voters don't use `acts_as_paranoia` and don't have any callbacks on destroy, it doesn't really matter whether we call `destroy!` or `delete`. We're using `delete` so there are no unintended side-effects that might affect voters with the same `user_id` and `poll_id` on Consul Democracy installations customizing this behavior.
This commit is contained in:
@@ -7,6 +7,7 @@ namespace :consul do
|
||||
|
||||
desc "Runs tasks needed to upgrade from 2.1.1 to 2.2.0"
|
||||
task "execute_release_2.2.0_tasks": [
|
||||
"db:mask_ips"
|
||||
"db:mask_ips",
|
||||
"polls:remove_duplicate_voters"
|
||||
]
|
||||
end
|
||||
|
||||
27
lib/tasks/polls.rake
Normal file
27
lib/tasks/polls.rake
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace :polls do
|
||||
desc "Removes duplicate poll voters"
|
||||
task remove_duplicate_voters: :environment do
|
||||
logger = ApplicationLogger.new
|
||||
logger.info "Removing duplicate voters in polls"
|
||||
|
||||
Tenant.run_on_each do
|
||||
duplicate_ids = Poll::Voter.select(:user_id, :poll_id)
|
||||
.group(:user_id, :poll_id)
|
||||
.having("count(*) > 1")
|
||||
.pluck(:user_id, :poll_id)
|
||||
|
||||
duplicate_ids.each do |user_id, poll_id|
|
||||
voters = Poll::Voter.where(user_id: user_id, poll_id: poll_id)
|
||||
voters.excluding(voters.first).each do |voter|
|
||||
voter.delete
|
||||
|
||||
tenant_info = " on tenant #{Tenant.current_schema}" unless Tenant.default?
|
||||
logger.info "Deleted duplicate record with ID #{voter.id} " \
|
||||
"from the #{Poll::Voter.table_name} table " \
|
||||
"with user_id #{user_id} " \
|
||||
"and poll_id #{poll_id}" + tenant_info.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
spec/lib/tasks/polls_spec.rb
Normal file
49
spec/lib/tasks/polls_spec.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "polls tasks" do
|
||||
let(:poll) { create(:poll) }
|
||||
let(:user) { create(:user, :level_two) }
|
||||
|
||||
describe "polls:remove_duplicate_voters" do
|
||||
before { Rake::Task["polls:remove_duplicate_voters"].reenable }
|
||||
|
||||
it "removes duplicate voters" do
|
||||
second_user = create(:user, :level_two)
|
||||
|
||||
voter = create(:poll_voter, poll: poll, user: user)
|
||||
second_voter = create(:poll_voter, poll: poll, user: second_user)
|
||||
other_user_voter = create(:poll_voter, poll: poll, user: create(:user, :level_two))
|
||||
other_poll_voter = create(:poll_voter, poll: create(:poll), user: user)
|
||||
|
||||
2.times { insert(:poll_voter, poll_id: poll.id, user_id: user.id) }
|
||||
insert(:poll_voter, poll_id: poll.id, user_id: second_user.id)
|
||||
|
||||
expect(Poll::Voter.count).to eq 7
|
||||
|
||||
Rake.application.invoke_task("polls:remove_duplicate_voters")
|
||||
|
||||
expect(Poll::Voter.count).to eq 4
|
||||
expect(Poll::Voter.all).to match_array [voter, second_voter, other_user_voter, other_poll_voter]
|
||||
end
|
||||
|
||||
it "removes duplicate voters on tenants" do
|
||||
create(:tenant, schema: "voters")
|
||||
|
||||
Tenant.switch("voters") do
|
||||
poll = create(:poll)
|
||||
user = create(:user, :level_two)
|
||||
|
||||
create(:poll_voter, poll: poll, user: user)
|
||||
insert(:poll_voter, poll_id: poll.id, user_id: user.id)
|
||||
|
||||
expect(Poll::Voter.count).to eq 2
|
||||
end
|
||||
|
||||
Rake.application.invoke_task("polls:remove_duplicate_voters")
|
||||
|
||||
Tenant.switch("voters") do
|
||||
expect(Poll::Voter.count).to eq 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user