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