Search code examples
ruby-on-railsrubyactiverecordruby-on-rails-5ruby-on-rails-5.2

How do I edit an old Rails migration to add a reference?


Preface

I know I could create a new migration, but I want to know if it is possible to edit an existing one in this way. This is just me learning Rails and trying out new things. There is no production version of this code running.

The issue

I am trying to get my series table in my schema to contain a reference to books, but it is not working.

Initial setup

rails db:migrate:status has me at this state:

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

And my file 20190402231737_create_books.rb looks like this:

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

Steps taken

First I rollback to the migration I want to edit (I have to run the following command 3 times - specifying a version # doesn't seem to work and I am not sure why):

rails db:rollback

Now rails db:migrate:status has me at this state:

 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

I added this line to the books migration:

t.references :series, foreign_key: true

Then I run the migrations:

rails db:migrate

Expected result

What I want is for my schema to be generated with this:

  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

Actual result

The line t.index ["series_id"], name: "index_books_on_series_id" never gets added to the schema.


Solution

  • You could probably solve this by adding a new index in a new migration.

    In general, rolling back migrations to alter them leads to all sorts of problems. What happens with the data in these tables? And so on.

    I suggest you make a new migration: rails g migration add_book_reference_on_series

    Then edit it like so:

    add_reference :series, :book, index: true
    

    I hope this helps.

    Best,