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"
|
logger.info "Removing duplicate partial results in polls"
|
||||||
|
|
||||||
Tenant.run_on_each do
|
Tenant.run_on_each do
|
||||||
duplicate_ids = Poll::PartialResult.where(option_id: nil)
|
Poll::Question.find_each do |question|
|
||||||
.select(:question_id, :booth_assignment_id, :date, :answer)
|
manageable_titles = PollPartialResultOptionFinder.new(question).manageable_choices.keys
|
||||||
.group(:question_id, :booth_assignment_id, :date, :answer)
|
|
||||||
.having("count(*) > 1")
|
|
||||||
.pluck(:question_id, :booth_assignment_id, :date, :answer)
|
|
||||||
|
|
||||||
duplicate_ids.each do |question_id, booth_assignment_id, date, answer|
|
question.question_options.each do |option|
|
||||||
partial_results = Poll::PartialResult.where(
|
titles = option.translations.where(title: manageable_titles).select(:title).distinct
|
||||||
question_id: question_id,
|
|
||||||
|
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,
|
booth_assignment_id: booth_assignment_id,
|
||||||
date: date,
|
date: date,
|
||||||
answer: answer,
|
answer: titles
|
||||||
option_id: nil
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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_results.excluding(partial_results.first).each do |partial_result|
|
||||||
partial_result.delete
|
partial_result.delete
|
||||||
|
|
||||||
tenant_info = " on tenant #{Tenant.current_schema}" unless Tenant.default?
|
|
||||||
log_message = "Deleted duplicate record with ID #{partial_result.id} " \
|
log_message = "Deleted duplicate record with ID #{partial_result.id} " \
|
||||||
"from the #{Poll::PartialResult.table_name} table " \
|
"from the #{Poll::PartialResult.table_name} table " \
|
||||||
"with question_id #{question_id}, " \
|
"with question_id #{question.id}, " \
|
||||||
"booth_assignment_id #{booth_assignment_id}, " \
|
"booth_assignment_id #{booth_assignment_id} " \
|
||||||
"date #{date} " \
|
"and date #{date}" + tenant_info.to_s
|
||||||
"and answer #{answer}" + tenant_info.to_s
|
|
||||||
logger.info(log_message)
|
logger.info(log_message)
|
||||||
duplicate_records_logger.info(log_message)
|
duplicate_records_logger.info(log_message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
desc "populates the poll_partial_results option_id column"
|
desc "populates the poll_partial_results option_id column"
|
||||||
task populate_partial_results_option_id: :remove_duplicate_partial_results do
|
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]
|
expect(Poll::PartialResult.all).to match_array [result, other_result, other_booth_result]
|
||||||
end
|
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
|
it "does not remove partial results with the same text and different options" do
|
||||||
question = create(:poll_question_multiple, :abcde, max_votes: 4)
|
question = create(:poll_question_multiple, :abcde, max_votes: 4)
|
||||||
option_a = question.question_options.find_by(title: "Answer A")
|
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
|
expect(Poll::PartialResult.count).to eq 1
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
describe "polls:populate_partial_results_option_id" do
|
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
|
it "removes duplicate partial results before populating the option_id column" do
|
||||||
question = create(:poll_question_multiple, :abc)
|
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 = {
|
result_attributes = {
|
||||||
question_id: question.id,
|
question_id: question.id,
|
||||||
booth_assignment_id: booth_assignment.id,
|
booth_assignment_id: booth_assignment.id,
|
||||||
@@ -391,14 +478,28 @@ describe "polls tasks" do
|
|||||||
result = create(:poll_partial_result, result_attributes)
|
result = create(:poll_partial_result, result_attributes)
|
||||||
insert(: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
|
result.reload
|
||||||
|
localized_result.reload
|
||||||
|
|
||||||
expect(result.option_id).to be nil
|
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")
|
Rake.application.invoke_task("polls:populate_partial_results_option_id")
|
||||||
result.reload
|
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(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
|
end
|
||||||
|
|
||||||
it "populates the option_id column on tenants" do
|
it "populates the option_id column on tenants" do
|
||||||
|
|||||||
Reference in New Issue
Block a user