Robby Kim
Robby Kim

Reputation: 464

Rails rename_column changing the column's type

I'm writing a down method in my migration to deal with reverting a migration that replaces a string field with a reference field. Here's the code:

class ChangeCars < ActiveRecord::Migration[5.1]
  def up
    rename_column :cars, :make_id, :make_id_string
    add_reference :cars, :make, foreign_key: true, optional: true

    Cars.all.each do |car|
      unless car.make_id_string.nil?
        make = Make.find_by(uuid: car.uuid)
        car.make_id = make
      end

      car.save!
    end

    remove_column :cars, :make_id_string
  end

  def down
    add_column :cars, :make_id_string, :string

    Cars.all.each do |car|
      unless car.make.nil?
        car.make_id_string = car.make.uuid
      end

      car.save!
    end

    # at this point :make_id_string -> String

    remove_reference :cars, :make, index: true, foreign_key: true
    rename_column :cars, :make_id_string, :make_id

    # at this point :make_id -> Fixnum
  end
end

It seems like when I'm removing the reference, I'm not completely flushing it out so when I replace the make_id field, it takes on that fixnum type.

Any suggestions are appreciated!

Upvotes: 1

Views: 142

Answers (1)

mrzasa
mrzasa

Reputation: 23327

  1. If you have real data in the make_id_string I would strongly suggest not to remove it. If you have some bugs in the migration, it would save you. Also reverting the migration would be far easier.

  2. If you want to iterate over all models in Car, don't use #each, because if loads all the cars to memory at once. Use #find_each that loads records in batches.

Upvotes: 1

Related Questions