2013-01-17 56 views
0

我正在研究Rails應用程序(Ruby 1.9.2/Rails 3.0.3),該應用程序隨時跟蹤不同團隊的人員及其成員。我遇到了一個可擴展的方法來組合重複的Person對象。 '組合'我的意思是刪除除重複的Person對象之外的所有對象,並更新所有引用以指向該Person的剩餘副本。下面是一些代碼:如何組合重複的rails對象並更新所有引用

型號:

Person.rb

class Person < ActiveRecord::Base 
    has_many :rostered_people, :dependent => :destroy 
    has_many :rosters, :through => :rostered_people 
    has_many :crews, :through => :rosters 

    def crew(year = Time.now.year) 
     all_rosters = RosteredPerson.find_all_by_person_id(id).collect {|t| t.roster_id} 
     r = Roster.find_by_id_and_year(all_rosters, year) 
     r and r.crew 
    end 
end 

Crew.rb

class Crew < ActiveRecord::Base 
    has_many :rosters 
    has_many :people, :through => :rosters 
end 

Roster.rb

class Roster < ActiveRecord::Base 
    has_many :rostered_people, :dependent => :destroy 
    has_many :people, :through => :rostered_people 
    belongs_to :crew 
end 

RosteredPerson.rb

class RosteredPerson < ActiveRecord::Base 
    belongs_to :roster 
    belongs_to :person 
end 

Person對象可以只用一個名字和姓氏創建,但他們有一個真正獨特的領域被稱爲iqcs_num(認爲它像一個社會安全號碼),它可以任意存儲在任一createupdate的操作。

所以createupdate行動中,我想執行重複的Person對象的檢查,刪除重複,然後更新所有crewroster引用指向剩餘Person

在每個型號上使用.update_all是否安全?這似乎是一種蠻橫的力量,尤其是因爲我將來可能會增加更多的依賴Person的模型,而且我不想記住保留find_duplicate函數。

感謝您的幫助!

回答

0

解決這個問題的'可擴展'方法是讓重複數據刪除過程成爲應用程序正常功能的一部分 - 每當您保存一條記錄時,請確保它不是重複的。您可以通過在Person模型中添加callback來完成此操作。也許是這樣的:

before_save :check_for_duplicate 

def check_for_duplicate 
    if iqcs_num 
    dup = Person.find_by_iqcs_num(self.iqcs_num) 
    if dup && dup.id != self.id 
     # move associated objects to existing record 
     dup.crews = dup.crews + self.crews 

     # update existing record 
     dup.update_attributes(:name => self.name, :other_field => self.other_field) 

     # delete this record 
     self.destroy 

     # return false, so that no other callbacks get triggered 
     return false 
    end 
    end 
end 

你要確保你的索引您存儲用戶對象上的iqcs_num列,因此,這種查找保持有效,因爲記錄的數量增長表 - 這將畢竟,每次更新人員記錄時都要執行此操作。

我不知道你可以保持回調是最新的 - 很可能不同類型的關聯對象必須以不同的方式移動。另一方面,它只存在於一個地方,無論如何它都是你添加關聯的地方 - 在模型中。

最後,爲了確保您的代碼正常工作,您可能需要在Person模型上添加驗證,以防止存在重複項。例如:

validates :iqcs_num, :uniqueness => true, :allow_nil => true 
+0

啊哈!這確實聽起來像是要走的路 - 我只關心更新'dup.crews = dup.crews + self。由於更多的關聯與「人」模型相關聯,因此「船員」聲明將成爲維護此站點的經典「難題」。但我想這是我需要記錄的東西......感謝您的幫助! – evanhsu

+0

...我可能會把這個與['reflect_on_all_associations'](http://apidock.com/rails/ActiveRecord/Reflection/ClassMethods/reflect_on_all_associations)方法的更多研究結合起來... – evanhsu

相關問題