我有一个Rails 2项目,通过连接表有很多关系。让我们调用表A,B和ABJ,其中ABJ具有属性a_id
和b_id
(以及不相关的问题id
和{created,updated}_at
)。 / p>
不幸的是,这种关系从一开始就被错误地创建,应该只是一个多(A has_many B's,B belongs_to A)。所以我创建了一个 up 迁移,将B直接与A重新关联。基本上,1)add_column a_id到B,2)为每个ABJ,把abj.a.id放到abj.b.a_id,3)drop_table:abj。这很好。
我还在 down 迁移中创建了“逆”操作,如果我需要(1)create_table abj,2)为每个B创建一个新的abj,那么abj.a_id = b.a_id和abj.b_id = b.id,3)从B)中删除_column a_id。这也很好。
随着“重新关联”这种关系与一个多的关系,期望不再使用的连接资源ABJ将消失,即删除模型,控制器,测试等。问题是如果我做需要返回,则运行 down 迁移将无效,因为在步骤2(对于每个B,创建一个新的abj),不再有任何{ {1}}因为我删除了模型。
那么有没有办法在迁移中制作一个“临时”模型,只是为了操纵数据库中的数据?或者您是否只是要求运行迁移的人在运行之前确定该模型是否存在?因为如果 down 迁移在步骤2中失败,那么步骤1已经创建了class ABJ < ActiveRecord::Base
表,然后您必须手动删除它或注释掉第1步代码在迁移之前再次运行它(然后在以后取消注释)。
想知道是否有任何好的解决方案。
答案 0 :(得分:6)
您可以在迁移中定义模型。只需将准系统定义放在迁移的顶部:
class Pancake < ActiveRecord::Base; end
如果你要放弃一张桌子,你需要注意当煎饼桌不存在时你不要在Pancake上调用方法。
答案 1 :(得分:1)
要么使用TomL的建议,要么使用手动SQL(假设您使用MySQL):
UPDATE
B, ABJ
SET
B.a_id = ABJ.a_id
WHERE
B.id = ABJ.b_id;
其他RDBMS使用JOINs允许类似的,更自然的语法。