diff --git a/app/models/course/assessment/answer.rb b/app/models/course/assessment/answer.rb index 2857ab6ccad..1f09e1f11a1 100644 --- a/app/models/course/assessment/answer.rb +++ b/app/models/course/assessment/answer.rb @@ -79,8 +79,10 @@ def validate_consistent_grade # # @return [Course::Assessment::Answer::AutoGrading] def ensure_auto_grading! - create_auto_grading! unless auto_grading - rescue ActiveRecord::RecordNotUnique + auto_grading || create_auto_grading! + rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique => e + raise e if e.is_a?(ActiveRecord::RecordInvalid) && e.record.errors[:answer_id].empty? + association(:auto_grading).reload auto_grading end diff --git a/spec/models/course/assessment/answer_spec.rb b/spec/models/course/assessment/answer_spec.rb index d83e1c1afde..3c9bbe1adb4 100644 --- a/spec/models/course/assessment/answer_spec.rb +++ b/spec/models/course/assessment/answer_spec.rb @@ -176,5 +176,28 @@ end end end + + describe '#ensure_auto_grading!' do + context 'when an existing auto grading already exists' do + let(:existing_record) do + # Duplicate the subject so the subject does not know about the grading. + create(:course_assessment_answer_auto_grading, answer: subject.class.find(subject.id)) + end + + it 'returns the existing grading' do + # Simulate a concurrent creation of an existing record. + expect(subject.auto_grading).to be_nil + existing_record + + expect(subject.send(:ensure_auto_grading!)).to eq(existing_record) + end + end + + context 'when no existing auto grading exists' do + it 'creates a new grading' do + expect(subject.send(:ensure_auto_grading!)).to be_persisted + end + end + end end end