У меня есть модель с «членом», «группой», «членством» и «пользователем». Данные организованы в виде древовидной структуры с группами, с которыми связаны члены. Члены без каких-либо групповых ассоциаций считаются потерянными и бесполезными для приложения.
Когда пользователь уничтожает группу, не должно оставаться ни одного члена-сироты. Другими словами: член должен быть уничтожен тогда и только тогда, когда удаляется последняя групповая ассоциация. Предпочтительно это должно происходить в одной транзакции, но наиболее важным аспектом является то, что потерянный объект не накапливается в базе данных с течением времени.
Удалять следует только участников и группы, связанные с пользователем. Группы, участники и членства, принадлежащие другим пользователям, не должны быть затронуты вообще. (Можно возразить, что глобальный метод очистки может быть запущен в любое время, но я хочу изолировать деструктивные операции, чтобы они затрагивали только объекты текущих пользователей.)
Мой вопрос: каков наиболее эффективный и элегантный способ реализовать эту функциональность в 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