我想在我的模型中添加一个功能来合并两个记录。如果我有例如PlayerA和PlayerB,并且想要销毁PlayerB但是将他所有的当前记录分配给PlayerA。我打算制作一个方法来查找他的所有记录并替换为PlayerA的id就像这样......
#...
Note.where(player_id: PlayerB.id).update_all(player_id: PlayerA.id)
HighScores.where(player_id: PlayerB.id).update_all(player_id: PlayerA.id)
Friends.where(player_id: PlayerB.id).update_all(player_id: PlayerA.id)
#...
现在,如果我这样做,我将不得不记住为将来为玩家模型创建的每个关联添加一个。有没有一种方法可以动态完成,通过一些方法来拉动所有关联,所以我不必为每个新关联手动添加?
答案 0 :(得分:1)
似乎是ActiveRecord::Reflection的正确位置。
Player.reflect_on_all_associations # returns an array of all associations
Player.reflect_on_all_associations(:has_many) # returns an array of all has_many associations
所以这样的事可能适合你:
associations = Player.reflect_on_all_associations(:has_many)
associations.each do |association|
associated_class = association.class_name.constantize # e.g. Note
foreign_key = association.foreign_key # e.g. player_id
associated_class.where(foreign_key => PlayerB.id).
update_all(foreign_key => PlayerA.id))
end
请注意,对于像has_and_belongs_to_many
这样的复杂关联,这可能会更棘手。为了简单起见,我不在此处讨论这种情况,但您可以基于association.class
实现一些条件逻辑,ActiveRecord::Reflection
是BelongsToReflection
子类之一(HasAndBelongsToManyReflection
,HasManyReflection
,HasOneReflection
,{{1}})。
答案 1 :(得分:0)
不确定是否有快速的方法,如果有的话,我很乐意听到,但是我做了很长的路。我用旧的数据保存了旧的数据"导入"状态,以便可以在需要时查看它而不会妨碍,并为每种关联类型创建每个记录的新版本,以及新玩家的详细信息。