【问题标题】:Rails migration: use different column as idRails 迁移:使用不同的列作为 id
【发布时间】:2011-07-10 21:15:39
【问题描述】:

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

【问题讨论】:

    标签: ruby-on-rails migration schema


    【解决方案1】:

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

    1. 确保您的姓名列在所有记录中都是唯一的
    2. 查找存储对您的对象的引用的所有其他对象,并将其从 id 更改为 name。

    如果您发现该列不是唯一的,您将不得不想出某种计划来更改它...例如名称字段中的名称 + id 用于重复或类似的东西。当然,所有这些都可以通过迁移来完成。

    我建议将 id 列保留在那里,但仅用于解决您在此过程中发现的问题

    举个例子,假设这是您围绕标签表的模型:

    class Tag < ActiveRecord::Base
    end
    

    假设您至少有另一个模型 Thing,它与 Tag 模型有简单的关联:

    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
    

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

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

    【讨论】:

    • 是的,我可以添加一些,但他没有提供任何模型或其他示例。给我几分钟,我会整理一些东西:)
    • 谢谢!我只是听取您的建议,离开 id 列并按 name 列搜索标签,特别是因为我将有多个用户制作自己的标签。
    猜你喜欢
    • 1970-01-01
    • 2013-12-28
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    相关资源
    最近更新 更多