如何编辑旧的 Rails 迁移以添加参考?

Posted

技术标签:

【中文标题】如何编辑旧的 Rails 迁移以添加参考?【英文标题】:How do I edit an old Rails migration to add a reference? 【发布时间】:2019-08-26 09:38:43 【问题描述】:

前言

我知道我可以创建一个新的迁移,但我想知道是否可以以这种方式编辑现有的迁移。这只是我学习 Rails 并尝试新事物的过程。此代码没有生产版本运行。

问题

我试图让我的架构中的series 表包含对books 的引用,但它不起作用。

初始设置

rails db:migrate:status 让我处于这种状态:

Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190330155354  Create articles
   up     20190401004837  Create comments
   up     20190402231737  Create books
   up     20190402233013  Create pages
   up     20190403221445  Create series

我的文件20190402231737_create_books.rb 看起来像这样:

class CreateBooks < ActiveRecord::Migration[5.2]
  def change
    create_table :books do |t|
      t.integer :series_number
      t.integer :year_published

      t.timestamps
    end
  end
end

采取的步骤

首先我回滚到我想编辑的迁移(我必须运行以下命令 3 次 - 指定版本号似乎不起作用,我不知道为什么):

rails db:rollback

现在rails db:migrate:status 让我处于这种状态:

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190330155354  Create articles
   up     20190401004837  Create comments
  down    20190402231737  Create books
  down    20190402233013  Create pages
  down    20190403221445  Create series

我在书籍迁移中添加了这一行:

t.references :series, foreign_key: true

然后我运行迁移:

rails db:migrate

预期结果

想要是用这个来生成我的架构:

  create_table "series", force: :cascade do |t|
    t.string "title"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["series_id"], name: "index_books_on_series_id"
  end

实际结果

t.index ["series_id"], name: "index_books_on_series_id" 行永远不会添加到架构中。

【问题讨论】:

为什么不创建新的迁移? 我知道我可以创建一个新的迁移,但我想知道是否可以通过这种方式编辑现有的迁移。这只是我学习 Rails 并尝试新事物的过程。没有运行此代码的生产版本。 【参考方案1】:

您可以通过在新迁移中添加新索引来解决此问题。

通常,回滚迁移以更改它们会导致各种问题。这些表中的数据会发生什么情况?等等。

我建议你进行新的迁移:rails g migration add_book_reference_on_series

然后像这样编辑它:

add_reference :series, :book, index: true

我希望这会有所帮助。

最好的,

【讨论】:

我知道我可以创建一个新的迁移,但我想知道是否可以通过这种方式编辑现有的迁移。这只是我学习 Rails 并尝试新事物的过程。没有运行此代码的生产版本。 您无法将系列引用添加到图书迁移中,因为系列表在您创建图书表的位置不存在。 啊!好的!这就说得通了!我有一种感觉,就是这样。是否可以“重组”迁移?重命名迁移以使其稍后发生是一种可行的技术吗? 是的。如果您还没有在生产中运行它们,那么您可以简单地重命名以重新排列。但是,如果它们在您的计算机以外的任何其他计算机上运行,​​请务必小心,这将对其他所有人的数据结构造成严重破坏。 是的,我明白了,你在说什么。这是一个可行的方法,虽然不漂亮。我将您的方法读作回滚到时间戳,但您只是回滚那个单个时间戳。【参考方案2】:

我将从上面引用原始问题中的文字。

前言。

我知道我可以创建一个新的迁移,但我想知道是否可以通过这种方式编辑现有的迁移。这只是我学习 Rails 并尝试新事物的过程。此代码没有生产版本运行。

这是编辑现有迁移的方式...

你可以使用->

rails db:migrate:down VERSION=20190402231737

无需多次回滚。

更改有问题的迁移,然后再次运行

rails db:migrate

但是,如果您在团队中工作并且在新环境中从头开始运行所有迁移可能会产生意外结果,并且可能会被破坏,因为会引用不存在的表,这可能是不安全的。

所以除非你知道自己在做什么,否则不应该这样做。

Changing Existing Migrations - Rails GuidesRollback a specific migration - ***

【讨论】:

以上是关于如何编辑旧的 Rails 迁移以添加参考?的主要内容,如果未能解决你的问题,请参考以下文章

Rails迁移以将主键添加到现有表

如何编写迁移以重命名 Rails 中的 ActiveRecord 模型及其表?

Rails 3 迁移:添加参考列?

Ruby on Rails:如何使用迁移向现有列添加非空约束?

您如何编写 Rails 迁移以删除 schema.rb 中的 :id => false 选项?

Rails DB 迁移 - 如何删除表?