У меня есть модель с «членом», «группой», «членством» и «пользователем». Данные организованы в древовидной структуре с группами, которые связаны с ними членами. Члены без каких-либо групповых ассоциаций считаются сиротами и бесполезны для приложения.Предотвращение осиротевших объектов, с has_many через ассоциации, в Rails 3
Когда пользователь уничтожает группу, не должно быть никаких сиротских членов. Другими словами: член должен быть уничтожен, если и только если последняя групповая ассоциация удалена. Предпочтительно это должно происходить в одной транзакции, но наиболее важным аспектом является то, что потерянный объект не накапливается в базе данных с течением времени.
Необходимо удалить только те члены и группы, которые связаны с пользователем. Группы, члены и члены, принадлежащие другим пользователям, не должны быть затронуты вообще. (Можно было бы утверждать, что глобальный метод очистки можно запускать в любое время, но я хочу изолировать деструктивные операции, чтобы воздействовать только на текущие объекты пользователей.)
Мой вопрос: что является самым эффективным и элегантным способом реализации этой функции в Rails 3? Моя текущая реализация, проиллюстрированная упрощенной моделью, описанной здесь, не удаляет члена из базы данных, если пользователь не удалит ее вручную (или что весь пользователь и все его данные удалены путем удаления каскада.)
class User < ActiveRecord::Base
has_many :groups, :foreign_key => 'owner_id', :dependent => :delete_all
has_many :members, :foreign_key => 'owner_id', :dependent => :destroy
end
class Member < ActiveRecord::Base
belongs_to :owner, :class_name => 'User'
has_many :memberships, :dependent => :destroy
has_many :groups, :through => :memberships
end
class Membership < ActiveRecord::Base
belongs_to :member
belongs_to :group
end
class Group < ActiveRecord::Base
belongs_to :owner, :class_name => 'User'
belongs_to :parent, :class_name => 'Group'
has_many :groups, :foreign_key => 'parent_id', :dependent => :destroy
has_many :memberships, :dependent => :destroy
has_many :members, :through => :memberships
end
Стоит отметить: это не будет работать с 'has_and_belongs_to_many' ассоциации в качестве модели вызывающей' after_destroy' больше не будет иметь 'id' и не будет в состоянии определить, какие объекты она используется ассоциироваться с. –