Add task to add option_id to existing partial results
This commit is contained in:
@@ -7,6 +7,6 @@ namespace :consul do
|
||||
|
||||
desc "Runs tasks needed to upgrade from 2.3.1 to 2.4.0"
|
||||
task "execute_release_2.4.0_tasks": [
|
||||
"polls:remove_duplicate_partial_results"
|
||||
"polls:populate_partial_results_option_id"
|
||||
]
|
||||
end
|
||||
|
||||
@@ -147,4 +147,41 @@ namespace :polls do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "populates the poll_partial_results option_id column"
|
||||
task populate_partial_results_option_id: :remove_duplicate_partial_results do
|
||||
logger = ApplicationLogger.new
|
||||
logger.info "Updating option_id column in poll_partial_results"
|
||||
|
||||
Tenant.run_on_each do
|
||||
Poll::Question.find_each do |question|
|
||||
options = question.question_options.joins(:translations).reorder(:id)
|
||||
existing_choices = question.partial_results.where(option_id: nil).distinct.pluck(:answer)
|
||||
|
||||
choices_map = existing_choices.to_h do |choice|
|
||||
[choice, options.where("lower(title) = lower(?)", choice).distinct.ids]
|
||||
end
|
||||
|
||||
manageable_choices, unmanageable_choices = choices_map.partition { |choice, ids| ids.count == 1 }
|
||||
|
||||
manageable_choices.each do |choice, ids|
|
||||
question.partial_results.where(option_id: nil, answer: choice).update_all(option_id: ids.first)
|
||||
end
|
||||
|
||||
unmanageable_choices.each do |choice, ids|
|
||||
tenant_info = " on tenant #{Tenant.current_schema}" unless Tenant.default?
|
||||
|
||||
if ids.count == 0
|
||||
logger.warn "Skipping poll_partial_results with the text \"#{choice}\" for the poll_question " \
|
||||
"with ID #{question.id}. This question has no poll_question_answers " \
|
||||
"containing the text \"#{choice}\"" + tenant_info.to_s
|
||||
else
|
||||
logger.warn "Skipping poll_partial_results with the text \"#{choice}\" for the poll_question " \
|
||||
"with ID #{question.id}. The text \"#{choice}\" could refer to any of these " \
|
||||
"IDs in the poll_question_answers table: #{ids.join(", ")}" + tenant_info.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,8 @@ require "rails_helper"
|
||||
describe "polls tasks" do
|
||||
let(:poll) { create(:poll) }
|
||||
let(:user) { create(:user, :level_two) }
|
||||
let(:booth_assignment) { create(:poll_booth_assignment) }
|
||||
let(:other_booth_assignment) { create(:poll_booth_assignment) }
|
||||
|
||||
describe "polls:remove_duplicate_answers" do
|
||||
before { Rake::Task["polls:remove_duplicate_answers"].reenable }
|
||||
@@ -227,9 +229,6 @@ describe "polls tasks" do
|
||||
describe "polls:remove_duplicate_partial_results" do
|
||||
before { Rake::Task["polls:remove_duplicate_partial_results"].reenable }
|
||||
|
||||
let(:booth_assignment) { create(:poll_booth_assignment) }
|
||||
let(:other_booth_assignment) { create(:poll_booth_assignment) }
|
||||
|
||||
it "removes duplicate partial results" do
|
||||
question = create(:poll_question_multiple, :abcde, poll: poll, max_votes: 4)
|
||||
|
||||
@@ -307,4 +306,127 @@ describe "polls tasks" do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "polls:populate_partial_results_option_id" do
|
||||
before do
|
||||
Rake::Task["polls:remove_duplicate_partial_results"].reenable
|
||||
Rake::Task["polls:populate_partial_results_option_id"].reenable
|
||||
end
|
||||
|
||||
it "populates the option_id column of existing partial results when there's one valid option" do
|
||||
yes_no_question = create(:poll_question, :yes_no, poll: poll)
|
||||
abc_question = create(:poll_question_multiple, :abc, poll: poll)
|
||||
option_a = abc_question.question_options.find_by(title: "Answer A")
|
||||
option_b = abc_question.question_options.find_by(title: "Answer B")
|
||||
|
||||
result = create(:poll_partial_result,
|
||||
question: yes_no_question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Yes",
|
||||
option: nil)
|
||||
abc_result = create(:poll_partial_result,
|
||||
question: abc_question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Answer A",
|
||||
option: nil)
|
||||
insert(:poll_partial_result,
|
||||
question: abc_question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Answer A",
|
||||
option_id: option_b.id)
|
||||
inconsistent_result = Poll::PartialResult.find_by!(option: option_b)
|
||||
invalid_result = build(:poll_partial_result,
|
||||
question: abc_question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Non existing",
|
||||
option: nil)
|
||||
invalid_result.save!(validate: false)
|
||||
|
||||
Rake.application.invoke_task("polls:populate_partial_results_option_id")
|
||||
result.reload
|
||||
abc_result.reload
|
||||
inconsistent_result.reload
|
||||
invalid_result.reload
|
||||
|
||||
expect(result.option_id).to eq yes_no_question.question_options.find_by(title: "Yes").id
|
||||
expect(abc_result.option_id).to eq option_a.id
|
||||
expect(inconsistent_result.option_id).to eq option_b.id
|
||||
expect(invalid_result.option_id).to be nil
|
||||
end
|
||||
|
||||
it "does not populate the option_id column when there are several valid options" 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")
|
||||
|
||||
result = create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "I",
|
||||
option: nil)
|
||||
|
||||
Rake.application.invoke_task("polls:populate_partial_results_option_id")
|
||||
result.reload
|
||||
|
||||
expect(result.option_id).to be nil
|
||||
end
|
||||
|
||||
it "removes duplicate partial results before populating the option_id column" do
|
||||
question = create(:poll_question_multiple, :abc)
|
||||
|
||||
result_attributes = {
|
||||
question_id: question.id,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Answer A",
|
||||
option_id: nil
|
||||
}
|
||||
result = create(:poll_partial_result, result_attributes)
|
||||
insert(:poll_partial_result, result_attributes)
|
||||
|
||||
result.reload
|
||||
expect(result.option_id).to be nil
|
||||
|
||||
Rake.application.invoke_task("polls:populate_partial_results_option_id")
|
||||
result.reload
|
||||
|
||||
expect(Poll::PartialResult.count).to eq 1
|
||||
expect(result.option_id).to eq question.question_options.find_by(title: "Answer A").id
|
||||
end
|
||||
|
||||
it "populates the option_id column on tenants" do
|
||||
create(:tenant, schema: "partial_results")
|
||||
|
||||
Tenant.switch("partial_results") do
|
||||
question = create(:poll_question_multiple, :abc)
|
||||
booth_assignment = create(:poll_booth_assignment)
|
||||
|
||||
create(:poll_partial_result,
|
||||
question: question,
|
||||
booth_assignment_id: booth_assignment.id,
|
||||
date: Date.current,
|
||||
answer: "Answer A",
|
||||
option: nil)
|
||||
end
|
||||
|
||||
Rake.application.invoke_task("polls:populate_partial_results_option_id")
|
||||
|
||||
Tenant.switch("partial_results") do
|
||||
expect(Poll::Question.count).to eq 1
|
||||
expect(Poll::PartialResult.count).to eq 1
|
||||
|
||||
question = Poll::Question.first
|
||||
option_a = question.question_options.find_by(title: "Answer A")
|
||||
|
||||
expect(Poll::PartialResult.first.option_id).to eq option_a.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user