2016-02-02 103 views
3

好的,我們f & ^%$ ** &編好了。重新關聯導軌中的所有相關模型

我們丟失了一堆用戶記錄。在某個時候,一個集成文件會重新插入一些丟失的記錄。

問題是新用戶的ID與原始用戶不同,所以舊用戶標識的所有現有相關內容都是孤立的。我現在需要重新將所有孤立的東西重新關聯到新的用戶標識。僅僅向新用戶提供備份中的舊ID是不夠的,因爲會有新的內容與新的用戶ID相關聯。

我們知道reflect_on_all_associations方法,但很難用於查找東西。但是,這可能是某種腳本的起點。

任何有關如何讓方法返回與特定模型相關的所有模型的線索都基於關聯,而不必指定或知道這些關聯?

回答

1

以下是使用reflect_all_associations的一種方法:您可以遍歷關聯,只選擇has_many和has_one,然後更新這些記錄。這裏是一個輔助類做的,你可以通過調用AssociationFixer.new(user_to_destroy,original_user_id).fix_associations執行作業:

class AssociationFixer 
    USER_ASSOCIATIONS = User.reflect_on_all_associations 

    def initialize(user_to_destroy, original_user_id) 
    @user_to_destroy = user_to_destroy 
    @original_user_id = original_user_id 
    end 

    def fix_associations 
    USER_ASSOCIATIONS.each do |association| 
     next if association.options.has_key? :through 
     if association.macro == :has_many 
     fix_has_many(association) 
     elsif association.macro == :has_one 
     fix_has_one(association) 
     end 
    end 
    end 

    def fix_has_many(association) 
    @user_to_destroy.send(association.name).each do |record| 
     if association.options.has_key? :foreign_key 
     record.send(assignment_method(association.foreign_key), @original_user_id) 
     else 
     record.user_id = @original_user_id 
     end 
     record.save 
    end 
    end 

    def fix_has_one(association) 
    if association.options.has_key? :foreign_key 
     @user_to_destroy.send(association.name).send(assignment_method(association.foreign_key), @original_user_id) 
    else 
     @user_to_destroy.send(assignment_method(association.name.user_id), @original_user_id) 
    end 
    record.save 
    end 

    def assigment_method(method_name) 
    method_name.to_s + '=' 
    end 
end 
0

這聽起來像是SQL的問題。我會考慮將備份表導入數據庫的單獨表中,如果有可能將它們加入到一個列,可能是email或user_name或其他東西。然後,您可以運行基於舊ID的選擇並更新爲新ID。祝你好運!

+1

用這種方法唯一的問題是,該協會將需要被我知道。 Rails已經知道所有的關聯,所以我希望能夠使用模型關聯來獲取所有關聯記錄。不過謝謝! – MoDiggity