2012-12-26 22 views
5

Voglio unire due profili in uno. Qual è il modo migliore per farlo in Rails.Unione di due/tre record nei binari

Ho due profili dire user1 e user2 e vi sono associate almeno 30 tabelle.

Ora voglio unirle insieme in modo che non ci dovrebbe essere un profilo dire user1 e user2 dovrebbe vengono eliminati ma tutti i dati associati di user2 ora dovrebbe associato con user1.

Ad esempio: supponiamo che user2 abbia due contatti e user1 abbia 3 contatti dopo aver unito l'utente user1 dovrebbe avere 5 contatti.

risposta

6

Qualcosa di simile

@user1 = User.find(1); 
@user2 = User.find(2); 

Contact.where("user_id = ?", @user2.id).update_all(:user_id => @user1.id) 
@user2.destroy 

in caso di soluzione generalize posto di file /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 

come usare

User < ActiveRecord::Base 
    has_many ... 

    acts_as_user_merge 

end 

@user1.merge(@user2) 

po 'disordinato e non testato ma dovrebbe darti un'idea

+0

voglio qualche soluzione generalize .... io non voglio farlo per tutte le mie 30 associazioni – Salil

0

Qualcosa del genere

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