2016-01-09 92 views
0

Rails应用程序中我做一个比较大规模的重构(在一个特性分支)的去除(和替换)几个has many :through类型关联。由于结构变化相对较大,我通过遍历'through'类中的所有对象并将其替换为随后保存的新对象来完成此操作。这比原始SQL更安全(也更容易),虽然速度较慢,但​​这是我愿意支付的价格。粗略地迁移看起来是这样的:轨道4:删除类(协)会迁移

def up 
    create_table :new_through_table ... 
    OldThroughTable.find_each do |x| 
    # ... data conversion 
    NewThroughTable.create(...) 
    end 
    drop_table :old_through_table 
end 

def down 
    # vice versa 
end 

在这个变化的过程中,我在app/models创建新类和旧的关联类现在都是多余的,一旦迁移完成,所以我删除的类文件和has_manybelongs_to代码行中的相关类并提交结果。

但是,由于旧的关联类现在不存在了,因此任何牵扯我的更改的人都无法运行迁移,因为旧的类文件不见了,旧的数据库结构不再映射到新的类结构。

我可以 - 理论上 - 写在迁移到不需要任何类(原始SQL),但是这似乎麻烦我 - 加,我错过任何确认和回调的类都有。我也可以将旧的类文件和关联留在那里,但我不太喜欢这个想法。

是否有在两个方向上写这样的迁移因此它可以可靠地同时保持代码干净的任何其他清洁的方式?

+0

你确认这个类的一个实例drop_table?我认为我从来没有遇到这个问题,尽管它过去一直关注我。 直接在你的数据库上创建一个'测试'表(不是通过你的应用程序,所以不会有模型定义)。使用“drop_table:test”创建迁移,如果有效,那么您应该很好。 –

+0

这不是drop_table命令,它是迁移过程中的数据转换,它需要循环旧模型和新模型。我添加了一个例子。 – Jens

回答

1

一种方法是把模型,迁移需要他们,到迁移,即

class SomeMigration < ActiveRecord::Migration 
    class SomeModel < ActiveRecord::Base 
    ... 
    end 

    def up 
    SomeModel.find_each do |record| 
     ... 
    end 

    drop_table :some_models 
    end 
end 

您将需要复制任何关联或验证你想迁移到使用。您最终将获得更大的迁移,但您确切知道迁移正在使用的是哪种模型代码,而不是运行迁移的最新代码。

+0

这可能确实有效。我会尽快尝试。谢谢! – Jens

+0

它曾经被记录 - http://guides.rubyonrails.org/v4.1/migrations.html#using-models-in-your-migrations –