Delete duplicate records in different languages
Also logs a message when duplicates have different amounts, keeping the first partial result and deleting the others.
This commit is contained in:
@@ -116,37 +116,58 @@ namespace :polls do
|
||||
logger.info "Removing duplicate partial results in polls"
|
||||
|
||||
Tenant.run_on_each do
|
||||
duplicate_ids = Poll::PartialResult.where(option_id: nil)
|
||||
.select(:question_id, :booth_assignment_id, :date, :answer)
|
||||
.group(:question_id, :booth_assignment_id, :date, :answer)
|
||||
.having("count(*) > 1")
|
||||
.pluck(:question_id, :booth_assignment_id, :date, :answer)
|
||||
Poll::Question.find_each do |question|
|
||||
manageable_titles = PollPartialResultOptionFinder.new(question).manageable_choices.keys
|
||||
|
||||
duplicate_ids.each do |question_id, booth_assignment_id, date, answer|
|
||||
partial_results = Poll::PartialResult.where(
|
||||
question_id: question_id,
|
||||
question.question_options.each do |option|
|
||||
titles = option.translations.where(title: manageable_titles).select(:title).distinct
|
||||
|
||||
groups = question.partial_results.where(option_id: nil, answer: titles)
|
||||
.select(:booth_assignment_id, :date)
|
||||
.group(:booth_assignment_id, :date)
|
||||
.having("count(*) > 1")
|
||||
.pluck(:booth_assignment_id, :date)
|
||||
|
||||
groups.each do |booth_assignment_id, date|
|
||||
partial_results = question.partial_results.where(
|
||||
option_id: nil,
|
||||
booth_assignment_id: booth_assignment_id,
|
||||
date: date,
|
||||
answer: answer,
|
||||
option_id: nil
|
||||
answer: titles
|
||||
)
|
||||
|
||||
tenant_info = " on tenant #{Tenant.current_schema}" unless Tenant.default?
|
||||
|
||||
amounts_by_id = partial_results.pluck(:id, :amount).to_h
|
||||
if amounts_by_id.values.uniq.size > 1
|
||||
log_message = "Found duplicate partial results with different amounts " \
|
||||
"for question_id #{question.id}, " \
|
||||
"booth_assignment_id #{booth_assignment_id} " \
|
||||
"and date #{date}. " \
|
||||
"Keeping ID #{partial_results.first.id} " \
|
||||
"with amount #{partial_results.first.amount}. " \
|
||||
"Deleting partial results with these IDs and amounts: " \
|
||||
"#{amounts_by_id.except(partial_results.first.id)}" + tenant_info.to_s
|
||||
logger.info(log_message)
|
||||
duplicate_records_logger.info(log_message)
|
||||
end
|
||||
|
||||
partial_results.excluding(partial_results.first).each do |partial_result|
|
||||
partial_result.delete
|
||||
|
||||
tenant_info = " on tenant #{Tenant.current_schema}" unless Tenant.default?
|
||||
log_message = "Deleted duplicate record with ID #{partial_result.id} " \
|
||||
"from the #{Poll::PartialResult.table_name} table " \
|
||||
"with question_id #{question_id}, " \
|
||||
"booth_assignment_id #{booth_assignment_id}, " \
|
||||
"date #{date} " \
|
||||
"and answer #{answer}" + tenant_info.to_s
|
||||
"with question_id #{question.id}, " \
|
||||
"booth_assignment_id #{booth_assignment_id} " \
|
||||
"and date #{date}" + tenant_info.to_s
|
||||
logger.info(log_message)
|
||||
duplicate_records_logger.info(log_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "populates the poll_partial_results option_id column"
|
||||
task populate_partial_results_option_id: :remove_duplicate_partial_results do
|
||||
|
||||
@@ -258,6 +258,60 @@ describe "polls tasks" do
|
||||
expect(Poll::PartialResult.all).to match_array [result, other_result, other_booth_result]
|
||||
end
|
||||
|
||||
it "removes duplicate partial results in different languages" do
|
||||
question = create(:poll_question_multiple, max_votes: 2)
|
||||
|
||||
create(:poll_question_option, question: question, title_en: "Yes", title_de: "Ja")
|
||||
create(:poll_question_option, question: question, title_en: "No", title_de: "Nein")
|
||||
create(:poll_question_option, question: question, title_en: "Maybe", title_de: "Vielleicht")
|
||||
|
||||
create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Yes",
|
||||
option: nil)
|
||||
create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Ja",
|
||||
option: nil)
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 2
|
||||
|
||||
Rake.application.invoke_task("polls:remove_duplicate_partial_results")
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 1
|
||||
end
|
||||
|
||||
it "does not remove duplicate partial results when many options are possible" do
|
||||
question = create(:poll_question, title: "How do you pronounce it?")
|
||||
|
||||
create(:poll_question_option, question: question, title_en: "A", title_es: "EI")
|
||||
create(:poll_question_option, question: question, title_en: "E", title_es: "I")
|
||||
create(:poll_question_option, question: question, title_en: "I", title_es: "AI")
|
||||
|
||||
create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "I",
|
||||
option: nil)
|
||||
create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "AI",
|
||||
option: nil)
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 2
|
||||
|
||||
Rake.application.invoke_task("polls:remove_duplicate_partial_results")
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 2
|
||||
end
|
||||
|
||||
it "does not remove partial results with the same text and different options" do
|
||||
question = create(:poll_question_multiple, :abcde, max_votes: 4)
|
||||
option_a = question.question_options.find_by(title: "Answer A")
|
||||
@@ -305,6 +359,34 @@ describe "polls tasks" do
|
||||
expect(Poll::PartialResult.count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
it "removes duplicates in different languages even when amounts differ" do
|
||||
question = create(:poll_question_multiple, max_votes: 2)
|
||||
|
||||
create(:poll_question_option, question: question, title_en: "Yes", title_de: "Ja")
|
||||
|
||||
create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Yes",
|
||||
option: nil,
|
||||
amount: 3)
|
||||
|
||||
create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Ja",
|
||||
option: nil,
|
||||
amount: 5)
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 2
|
||||
|
||||
Rake.application.invoke_task("polls:remove_duplicate_partial_results")
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "polls:populate_partial_results_option_id" do
|
||||
@@ -381,6 +463,11 @@ describe "polls tasks" do
|
||||
it "removes duplicate partial results before populating the option_id column" do
|
||||
question = create(:poll_question_multiple, :abc)
|
||||
|
||||
localized_question = create(:poll_question_multiple)
|
||||
create(:poll_question_option, question: localized_question, title_en: "Yes", title_de: "Ja")
|
||||
create(:poll_question_option, question: localized_question, title_en: "No", title_de: "Nein")
|
||||
create(:poll_question_option, question: localized_question, title_en: "Maybe", title_de: "Vielleicht")
|
||||
|
||||
result_attributes = {
|
||||
question_id: question.id,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
@@ -391,14 +478,28 @@ describe "polls tasks" do
|
||||
result = create(:poll_partial_result, result_attributes)
|
||||
insert(:poll_partial_result, result_attributes)
|
||||
|
||||
localized_result_attributes = {
|
||||
question: localized_question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
option: nil
|
||||
}
|
||||
localized_result = create(:poll_partial_result, localized_result_attributes.merge(answer: "Yes"))
|
||||
create(:poll_partial_result, localized_result_attributes.merge(answer: "Ja"))
|
||||
|
||||
result.reload
|
||||
localized_result.reload
|
||||
|
||||
expect(result.option_id).to be nil
|
||||
expect(localized_result.option_id).to be nil
|
||||
|
||||
Rake.application.invoke_task("polls:populate_partial_results_option_id")
|
||||
result.reload
|
||||
localized_result.reload
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 1
|
||||
expect(Poll::PartialResult.count).to eq 2
|
||||
expect(result.option_id).to eq question.question_options.find_by(title: "Answer A").id
|
||||
expect(localized_result.option_id).to eq localized_question.question_options.find_by(title: "Yes").id
|
||||
end
|
||||
|
||||
it "populates the option_id column on tenants" do
|
||||
|
||||
Reference in New Issue
Block a user