2012-07-01 122 views
4

我有一個帶有「member」,「group」,「membership」和「user」的模型。數據以具有與其關聯的成員的組的樹結構進行組織。沒有任何團體協會的會員被認爲是孤兒,對申請沒有任何用處。在Rails 3中通過關聯來防止孤立對象,通過關聯has_many

當用戶銷燬一個組時,不應該留下孤立的成員。換句話說:當且僅當最後一個羣組關聯被移除時,成員應該被銷燬。最好這應該發生在單個事務中,但最重要的方面是孤立的對象不會隨着時間在數據庫中累積。

只應刪除與用戶關聯的成員和組。其他用戶擁有的團體,成員和會員資格根本不應受到影響。 (有人可能會爭辯說,全局清理方法可以隨時運行,但我希望隔離破壞性操作隻影響當前用戶對象。)

我的問題:什麼是最有效和最優雅的方式來實現此功能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 

回答

8

我通過在Membership類中添加一個回調函數來解決這個問題,當成員資格被銷燬時它會通知Member。如果成員對象不再具有任何組關聯,那麼成員對象會自行銷燬。

class Membership < ActiveRecord::Base 
    belongs_to :member 
    belongs_to :group 

    after_destroy :notify_member 

    def notify_member 
    member.destroy_if_empty_groups 
    end 
end 

class Member < ActiveRecord::Base 
    belongs_to :owner, :class_name => 'User'  
    has_many :memberships, :dependent => :destroy 
    has_many :groups, :through => :memberships 

    def destroy_if_empty_groups 
    if groups.count == 0 
     self.destroy 
    end 
    end 
end 
+1

值得注意的是:這不會以'has_and_belongs_to_many'協會作爲模型調用'after_destroy'將不再有'id',將無法確定它曾經與之相關聯的對象工作。 –

相關問題