2016-02-02 168 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