Rails 3 has_many изменен?

Мне нужно отслеживать изменения (добавления и удаления) ассоциации, созданной следующим образом:

has_many :listing_services
has_many :services, through: :listing_services

Для нормальных атрибутов упрощенным способом является проверка l.changes[attribute] в before_save или l.previous_changes[attribute] в after_save.

Вопрос в том, что лучший способ сделать это для атрибутов has_many?

Ответ 1

Я не использовал метод changes. Но я уверен, что вы всегда можете использовать магические методы <attribute_name>_changed? и <attribute_name>_was:

services.any? {|s| s.attribute_name_changed?}
services.map(&:attribute_name_was)

См. Ryan Bates railscast для получения дополнительной информации: # 109 эпизод

UPDATE: вы можете передать :after_delete и :after_add обратные вызовы в has_many:

has_many :items, :after_add => :my_method_or_proc1, :after_remove => :my_method_or_proc2

Будьте осторожны, используя эти обратные вызовы и обращайте внимание на то, как они работают. Они вызываются на items.build и items.create один раз. Поэтому, если вы вызываете items.build и затем сохраняете родительский объект (например, с вложенными атрибутами), after_add вызов after_add будет вызываться только один раз при создании связанного объекта. Это означает, что если у родителя есть валидация, тогда созданные items не будут сохранены в базе данных, и вы не сможете положиться на after_add вызов after_add. Другими словами, он не говорит, что добавленная запись ассоциации была сохранена в БД. Таким образом, у вас есть гарантия того, что элемент будет добавлен и сохранен только на items.create. Надеюсь, вы понимаете это разъяснение.