Привет,
Я представляю довольно простой SQL-подход только с одним предупреждением: добавьте дополнительный столбец, называемый чем-то вроде list_position
, и добавьте уникальный индекс в таблицу отношений класса-студента, состоящую изclassroom_id
, student_id
и list_position
.
Вставка, что происходит, путем установки list_position
числа учащихся в классе плюс один.Код Ruby, вероятно, будет где-то рядом
classroomStudent = ClassroomStudent.new
classroomStudent.list_position = classroom.size + 1
until classroomStudent.save
classroomStudent.list_position += 1
do_stuff_about_not_enough_room if classroomStudent.list_position > MAX_SIZE
end
Результат: если две вставки попытаются одновременно вставить учащегося в один и тот же класс, уникальный индекс не даст учиться одному ученику (INSERT
не удалось).Это означает, что вам, возможно, придется повторить попытку до list_position=MAX_SIZE
, но гарантировано, что у вас никогда не будет слишком много учеников в классе.Вы также можете использовать этот подход для создания очереди ожидания.
Если у вас уже есть данные в вашей реляционной таблице, вам сначала нужно будет добавить значение для list_position
.Я бы предположил, что что-то вроде
UPDATE ClassroomStudents AS c1 SET c1.list_position = COALESCE((SELECT MAX(c2.list_position) FROM ClassroomStudents AS c2 WHERE c2.classroom_id = c1.classroom_id), 0) + 1;
сделало бы эту работу здесь, хотя это могло бы быть немного медленной стороной.
Я знаю, что у решения все еще есть некоторые грубые края, но возможно это помогает.
С уважением
TC