You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: question_bundle_assignment_concern.rb
    path of file: ./repos/coursemology2/app/controllers/concerns/course/assessment
    
    the code of the file until where you have to start completion: # frozen_string_literal: true
module Course::Assessment::QuestionBundleAssignmentConcern
  extend ActiveSupport::Concern

  # All validations need to present a ValidationResult of this form, which will be consumed by the view.
  # This struct is loosely inspired by Rails' model validation, but heavily extended.
  # rubocop:disable Layout/CommentIndentation
  ValidationResult = Struct.new(
    :type,              # Hard or soft
    :pass,              # Whether this should be displayed as a tick or cross on the validation summary
    :score_penalty,     # For selecting the best randomized outcome
    :info,              # For displaying additional information. I18n string.
    :offending_cells,   # For highlighting the cell and displaying
    
    def save(assignment_set)
      # Deletion must be done atomically to prevent race conditions
      @assessment.question_bundle_assignments.where(submission: nil).delete_all
      new_question_bundle_assignments = []
      assignment_set.assignments.each do |student_id, assigned_group_bundles|
        assigned_group_bundles.each do |group_id, bundle_id|
          next if group_id.nil? || bundle_id.nil?

          new_question_bundle_assignments << Course::Assessment::QuestionBundleAssignment.new(
            user_id: student_id,
            assessment_id: @assessment.id,
            bundle_id: bundle_id
          )
        end
      end
      Course::Assessment::QuestionBundleAssignment.import! new_question_bundle_assignments
    end

    def randomize
      # Naive strategy: For each group, add a random bundle
      AssignmentSet.new(@students, @group_bundles).tap do |assignment_set|
        @students.each do |student|
          @group_bundles.each do |_, bundles|
            assignment_set.add_assignment(student, bundles.sample)
          end
        end
      end
    end

    def validate(assignment_set)
      [
        validate_no_overlapping_questions,
        validate_no_empty_groups,
        validate_one_bundle_assigned(assignment_set),
        validate_no_repeat_bundles(assignment_set)
      ].reduce(&:merge)
    end

    private

    def validate_no_overlapping_questions
      questions = Course::Assessment::Question.
                  where(id: @assessment.question_bundle_questions.group(:question_id).
                            having('count(*) > 1').
                            select(:question_id)).
                  pluck(:title).
                  to_sentence
      {
        no_overlapping_questions:
          ValidationResult.new(
            type: :hard,
            pass: questions.empty?,
            info: questions.empty? ? nil : t_scoped('.no_overlapping_questions.fail', questions: questions)
          )
      }
    end

    def validate_no_empty_groups
      groups = @assessment.question_groups.
               where.not(id: @assessment.question_bundles.select(:group_id)).
               pluck(:title).to_sentence
      {
        no_empty_groups:
          ValidationResult.new(
            type: :hard,
            pass: groups.empty?,
            info: groups.empty? ? nil : t_scoped('.no_empty_groups.fail', groups: groups)
          )
      }
    end

    def validate_one_bundle_assigned(assignment_set)
      student_ids = Set.new
      offending_cells = {}
      assignment_set.assignments.each do |student_id, assignment|
        assignment_set.group_bundles.each_key do |group_bundle|
          if assignment[group_bundle].nil?
            student_ids << student_id
            offending_cells[[student_id, group_bundle]] = t_scoped('.one_bundle_assigned.missing_bundle')
          end
        end
        if assignment[nil].present?
          student_ids << student_id
          offending_cells[[student_id, nil]] = t_scoped('.one_bundle_assigned.unbundled')
        end
      end