Rails迁移:使用不同的列作为id

时间:2011-07-10 21:15:40

标签: ruby-on-rails migration schema

我刚开始学习Rails迁移。我有一个名为tags的表格,其中列name [字符串](以及自动生成的id列)。我想迁移它,以便该表使用name列作为id和主键。如何确保所有现有记录都适用于新架构?

1 个答案:

答案 0 :(得分:3)

这种方法很简单,但执行似乎有风险。让迁移工作起来相当直接,但是下降了吗?不确定。

  1. 确保您的名称列在所有记录中都是唯一的
  2. 查找存储对象引用的所有其他对象,并将其从id更改为name。
  3. 如果您发现该列不是唯一的,您将不得不想出一些改变它的计划......比如名称字段中的名称+ id,用于重复或类似的东西。当然,所有这些都可以通过迁移来完成。

    我建议将id列留在那里,但只用它来解决你在路上发现的问题

    举例来说,假设这是围绕标签表的模型:

    class Tag < ActiveRecord::Base
    end
    

    假设您至少拥有与标记模型有简单关联的其他模型Thing:

    class Thing < ActiveRecord::Base
       has_one :tag
    end
    

    在Things表上有一个tag_id列。我添加一个名为tag_name的列,更改关联以使外键指向此新列...

    class Thing < ActiveRecord::Base
      has_one :tag, :foreign_key => "tag_name"
    end
    

    这告诉Rails这些事情之间的关联是通过新列。按照惯例,它会寻找“tag_id”。

    鉴于此更改,您可以进入迁移并:

    add_column :things, :tag_name, :string
    
    Thing.all.each do |thing| 
      if thing.tag
        thing.tag_name = thing.tag.name
      end
    end
    
    remove_column :things, :tag_id
    

    这是一个快速而肮脏的例子,我可能错过了一些东西。关键是要添加新列,移动关联,删除旧列。

    还有其他情况,例如模型涉及多对多关联或某些多态关联的情况,但在这些情况下,一般方法会类似。