Here's my situation: I have 2 person objects, person1 and person2, which were created from two different external data sources. I have a manual process that I use that has determined that person1 and person2 actually refer to the same person, so what I want to do is "merge" them into a single person, and remove the duplicate.
I have no problem doing this on a field by field basis for the object itself, but the thing that gets tricky, and will be hard to maintain if I do it badly, is that these people have associations (don't we all). What I want to do is after copying the appropriate fields into person1 (which I'll use going forward), I want to move the associations from person2 to person1 as well.
I think my question boils down to this: Is there a way to 1) iterate over each association for an object, and 2) determine the foreign_key field for that association. I'm pretty sure that if I were able to do those things I could write a method that automatically moved each associated record from person2 to person1, and not change that code if I add or remove an association.
Any ideas on how to do this?
Thanks.
Edit: I've implemented (as quickly and dirtily as possible while it seems to work) code based on the pointers given in Duncan's answer. Just in case this helps anyone, this is a rough outline of how you could move all the associated objects from one objects (@p2 in this case) to another (@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
To programatically inspect an ActiveRecord object's associations you'll want to use
ActiveRecord::Reflection
. The class methods defined here return collections comprised ofActiveRecord::Reflection::AssociationReflection
from which you can extract the foreign key, primary key, table name, etc...