Определите, были ли добавлены / удалены дочерние элементы в Rails Callback

Сценарий:

Я имею отношения habtm и хотел бы определить, были ли добавлены или удалены дети в одном направлении. Я пытаюсь использовать обратные вызовы, но обнаружил, что у меня нет записей об изменениях детей. Есть ли что-то вроде course.students.changed?


С помощью:

  • Rails 3.0.3
  • Ruby 1.9.2p0

Таблицы:

студенты - идентификатор, имя, фамилия
курсы - идентификатор, имя, местоположение
courses_students - course_id, student_id


Модели:

class Course
  # Callbacks
  before_save :student_maintenance

  # Relationships
  has_and_belongs_to_many :students

  protected
  def student_maintenance
    # I want to do something like
    students.changed?
      students.changes.each do |student|
        if marked_for_deletion
          # do something
        elsif marked_for_addition
          # do something else
        end
      end
    end
  end
end

class Student
  # Relationships
  has_and_belongs_to_many :courses
end

2 ответа

Решение

Если вы хотите записать, когда студент был добавлен или удален из курса, почему бы не использовать класс для таблицы соединений *courses_students*? Так как это место, где запись будет фактически создана или уничтожена, вы можете легко использовать обратные вызовы after_create/after_destroy.

Аналогично ответу Поларблау, но, надеюсь, объяснение немного больше:

В текстовых терминах UML отношения могут быть такими:

Course ------*-> Student

Читайте: курс имеет 0 для многих студентов

Вы можете добавлять и удалять студентов из ассоциации по желанию.

Однако вам интересно узнать больше об ассоциации, то есть когда студент был добавлен или исключен из курса. Эта "дополнительная" информация об ассоциации приводит к обнаружению, что вам нужен еще один класс, известный как "Класс ассоциации".

Так что теперь вы должны вставить этот класс между вашими существующими классами, так что позволите себе называть его "Регистрация":

Course ------*->Registration------1->Student

Читайте: курс имеет 0 для многих регистрации. В каждой регистрации должен быть ровно 1 студент.

Класс Registration может выглядеть так:

+--------------+
| Registration |
+--------------|
| student      |
| time_added   |
| time_dropped |
+--------------+

Таким образом, вы можете легко получить список текущих студентов для курса (где time_dropped равно нулю). Или список пропущенных студентов (где time_dropped не ноль).

Другие вопросы по тегам