【问题标题】:Merging two/three records in rails合并 Rails 中的两个/三个记录
【发布时间】:2012-12-26 12:56:55
【问题描述】:

我想将两个配置文件合并为一个。在 Rails 中执行此操作的最佳方法是什么。

我有两个配置文件,分别是 user1user2,并且至少有 30 个表与它们相关联。

现在我想将它们合并在一起,这样应该有一个个人资料说user1user2 应该被删除,但所有相关数据的user2 现在应该user1 关联

例如:假设user2有两个联系人,user1有3个联系人,合并用户user1应该有5个联系人。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 merge merging-data


    【解决方案1】:

    类似的东西

    @user1 = User.find(1);
    @user2 = User.find(2);
    
    Contact.where("user_id = ?", @user2.id).update_all(:user_id => @user1.id)
    @user2.destroy
    

    在泛化解决方案的情况下 放置文件/lib/acts_as_user_merge.rb

    module UserMerge
      module ActsAsUserMerge
        module Base
          def self.included(klass)
            klass.class_eval do
              extend Config
            end
          end
        end
    
        module Config
            def acts_as_user_merge
                include ::UserMerge::ActsAsUserMerge::InstanceMethods
            end
        end
    
        module InstanceMethods    
          def merge(user)
            models = Array.new
            models_names = User.reflections.collect{|a, b| b.class_name if b.macro==:has_many}.compact
            models_names.each do |name|
              models << Object.const_get name
            end
            models.each do |model|
              model.where("user_id = ?", user.id).update_all(:user_id => self.id)
            end
            user.destroy
          end
        end
      end
    end
    
    ::ActiveRecord::Base.send :include, ::UserMerge::ActsAsUserMerge::Base
    

    如何使用

    User < ActiveRecord::Base
      has_many ...
    
      acts_as_user_merge
    
    end
    
    @user1.merge(@user2)
    

    有点乱,没有经过测试,但应该给你一个想法

    【讨论】:

    • 我想要一些通用的解决方案....我不想为我所有的 30 个关联都这样做
    【解决方案2】:

    类似的东西

    def merge_users(dead, user)
      User.reflections.each do |assoc, reflection|
        foreign_key = reflection.foreign_key
        case reflection.macro
        when :has_many, :has_one then
          unless reflection.options[:through]
            reflection.klass.where(foreign_key => dead.id).update_all(foreign_key => user.id) # if id is a primary key
          end
          if options[:as] # polymorphic
            if reflection.macro == :has_many
              dead.send("#{options[:as].pluralize}")).each { |r| user.send("#{options[:as].pluralize}<<", r) }
            else
              user.send("#{options[:as]}=", dead.send("#{options[:as]}"))
              user.save
            end
          end
        when :belongs_to then
          if options[:polymorphic]
            user.send("#{assoc}=", deaf.send(assoc))
            user.save
          else
            user.update_attribute(foreign_key, dead.send(foreign_key))
          end
        when :has_and_belongs_to_many then
          dead.send("#{assoc}")).each { |r| user.send("#{assoc}<<", r) }
        end
    
      end
    end
    
    merge_users(dead_user, user)
    dead_user.destroy
    

    【讨论】:

      【解决方案3】:

      本文深入讨论了这个问题,并提供了它的工作代码:http://ewout.name/2010/04/generic-deep-merge-for-activerecord/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多