Qual a melhor forma de “mesclar” dois objetos e suas associações em trilhos?
Aqui está a minha situação: eu tenho 2 objetos de pessoa, person1 e person2, que foram criados a partir de duas fontes de dados externas diferentes. Eu tenho um processo manual que eu uso que determinou que pessoa1 e pessoa2 realmente se referem à mesma pessoa, então o que eu quero fazer é "mesclá-los" em uma única pessoa e remover a duplicata.
Eu não tenho nenhum problema em fazer isso em uma base de campo por campo para o objeto em si, mas o que fica complicado, e será difícil de manter se eu fizer mal, é que essas pessoas têm associações (não todos nós). O que eu quero fazer é depois de copiar os campos apropriados para person1 (que eu vou usar daqui para frente), eu quero mover as associações de person2 para person1 também.
Eu acho que a minha pergunta se resume a isso: Existe uma maneira de 1) iterar sobre cada associação para um objeto, e 2) determinar o campo foreign_key para essa associação. Tenho certeza de que, se eu fosse capaz de fazer essas coisas, poderia escrever um método que movesse automaticamente cada registro associado de person2 para person1 e não alterasse esse código se eu adicionasse ou removesse uma associação.
Algumas ideias em como fazer isso?
Obrigado.
Edit: Eu tenho implementado (o mais rápido e dirilmente quanto possível, enquanto parece funcionar) código baseado nos ponteiros dados na resposta de Duncan. Apenas no caso de isso ajudar alguém, este é um esboço de como você poderia mover todos os objetos associados de um objeto (@ p2 neste caso) para outro (@ p1).
Person.reflect_on_all_associations.each do |assoc|
if assoc.macro == :has_many
@p2.send(assoc.name).each do |assoc_obj|
assoc_obj.update_attribute(assoc.primary_key_name, @p1.id)
end
elsif assoc.macro == :has_one
@p2.send(assoc.name).update_attribute(assoc.primary_key_name, @p1.id)
end
end