¿Cuál es la mejor manera de “fusionar” dos objetos y sus asociaciones en los carriles?

Aquí está mi situación: tengo objetos de 2 personas, person1 y person2, que se crearon a partir de dos fuentes de datos externas diferentes. Tengo un proceso manual que utilizo que ha determinado que person1 y person2 realmente se refieren a la misma persona, así que lo que quiero hacer es "fusionarlos" en una sola persona y eliminar el duplicado.

No tengo problemas para hacer esto campo por campo para el objeto en sí, pero lo que se complica y será difícil de mantener si lo hago mal, es que estas personas tienen asociaciones (no todos). Lo que quiero hacer es después de copiar los campos apropiados en person1 (que usaré en adelante), quiero mover las asociaciones de person2 a person1 también.

Creo que mi pregunta se reduce a esto: ¿hay una manera de 1) iterar sobre cada asociación para un objeto, y 2) determinar el campo foreign_key para esa asociación. Estoy bastante seguro de que si pudiera hacer esas cosas, podría escribir un método que moviera automáticamente cada registro asociado de person2 a person1, y no cambiar ese código si agrego o elimino una asociación.

¿Alguna idea sobre cómo hacer esto?

Gracias.

Edición: He implementado (lo más rápido y lo más posible posible, mientras parece funcionar) el código basado en los indicadores que figuran en la respuesta de Duncan. En caso de que esto ayude a alguien, este es un resumen aproximado de cómo podría mover todos los objetos asociados de un objeto (@ p2 en este caso) a otro (@ 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

Respuestas a la pregunta(1)

Su respuesta a la pregunta