Quiz Management & Question Bank

Published: (December 30, 2025 at 05:06 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Data Model

  • One Quiz has many Questions
  • One Question has many Options
  • One Option can be marked as the correct answer

These nested relations appear simple during initial data creation but become significantly more complex when entering the editing process.

Complex Data Editing

A typical editing workflow might look like this:

  1. A teacher opens the quiz editor.
  2. Changes the quiz title.
  3. Deletes question #2.
  4. Edits the text of question #5.
  5. Adds a new question at the end.

All changes are sent to the backend with a single Save click. The backend must decide how to apply these modifications.

Approaches

ApproachProsCons
Partial Update (Diffing)Updates only changed parts.Complex, hard to maintain, prone to bugs in nested relations.
Full ReplacementSimple implementation.Risk of losing data references.

Modified Full Replacement (Academic Suite)

Academic Suite uses a modified full replacement wrapped in a database transaction to balance simplicity, data consistency, and safety. The entire update process is performed atomically; if any step fails, all changes are rolled back.

UpdateQuiz Implementation (handlers/quiz.go)

// Go (gorm)
err := database.DB.Transaction(func(tx *gorm.DB) error {
    // 1. Update main quiz data (title, duration, etc.)
    if err := tx.Save(&quiz).Error; err != nil {
        return err
    }

    // 2. Delete all old questions
    if err := tx.Delete(&models.Question{}, "quiz_id = ?", id).Error; err != nil {
        return err
    }

    // 3. Re‑insert questions from request
    for _, q := range req.Questions {
        q.QuizID = id
        if err := tx.Create(&q).Error; err != nil {
            return err
        }
    }

    return nil
})

Consequences

  • Question IDs change on every edit.
  • If answers or attempts tables reference question_id, student grade data can be corrupted.

Production Safeguards

  • Quizzes that are Active or have Attempts should be locked (frozen).
  • Alternatively, use soft delete or versioning for questions to preserve exam history.

Excel Question Import

Typing dozens of questions via a web form is inefficient, so Academic Suite provides an import feature from Excel (.xlsx) files.

  • Library used: github.com/xuri/excelize/v2

Data Validation Challenges

Excel files are free‑form:

  • Columns can be empty.
  • Formatting can be inconsistent.
  • Correct answers may be in the wrong position.

The backend validates each row individually:

// Go
for i, row := range rows {
    if len(row) < 7 {
        errors = append(errors, fmt.Sprintf(
            "Row %d: Incomplete columns",
            i+1,
        ))
        continue
    }
    // Further parsing and validation...
}

Benefits

  • Valid rows are still saved.
  • Problematic rows are reported specifically to the user, improving the experience without sacrificing data consistency.

Efficient Data Retrieval

To display a quiz with all its questions and answer options, Academic Suite uses GORM’s eager loading, preventing the N+1 query problem.

// Go (gorm) – eager loading
database.DB.
    Preload("Questions").
    Preload("Questions.Options").
    First(&quiz, "id = ?", id)

With eager loading, performance remains stable even for quizzes with a large number of questions.

Summary

In this chapter we built the foundation of a stable and scalable Question Bank and Quiz Management system. Key points covered:

  • Challenges of nested updates.
  • Transaction strategies to maintain data consistency.
  • Risks of editing active quizzes and mitigation techniques.
  • User‑friendly Excel import with row‑level validation.
  • Eager loading techniques for optimal performance.

Next up: Chapter 5 will dive into the Exam Engine, covering timer settings, exam status, and precise grading mechanisms.

Back to Blog

Related posts

Read more »

ALL ABOUT REST API

Forem Feed !Forem Logohttps://media2.dev.to/dynamic/image/width=65,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.co...

Spring Data JPA Relationships

Introduction Happy New Year! In the past ten days of my full‑stack journey, I have been working on projects right after joining. Initially, I struggled with Re...