How to change already added string column to a Reference in Rails

Viewed 6309

I've already created a model in Rails to collect some user information

I created the columns as :string initially but I've since changed the way this data is looked up and entered by using separate populated models.

Now instead of entering into these fields as string - i want these columns to be "references" instead.

Is there an easy way to change from the string to reference without having to create a new model entirely?

*do not need to save the existing data

5 Answers

Here is another solution, without dropping the column itself (not exactly in my case). I'm not sure though if this is the best solution.

In my case, I have a tickets table that holds purchase_uid in itself. I decided to keep purchases in another table after making the necessary improvements in our backend. Purchases table has uuid as the primary key. Given this background, here is my migration to change my column into a reference.

class AddPurchaseRelationToTickets < ActiveRecord::Migration[5.2]
  def up
    change_column :tickets, :purchase_uid, :uuid, references: :purchase, foreign_key: true, using: 'purchase_uid::uuid'
  end

  def down
    change_column :tickets, :purchase_uid, :string
  end
end

In my case, since string doesn't automatically cast into uuid, purchase_uid were dropped and recreated as well. However, if you decide to keep the column type same, I don't think it will be a problem.

Wanted to add a simpler alternative to the accepted answer that preserves data:

class ChangeStringToInt < ActiveRecord::Migration[5.1]
  def up
    change_column :table_name, :field_name, :integer, null: false, references: :table_referenced, using: 'field_name::integer'
    add_index :chapter_actions, :field_name
  end

  def down
    change_column :table_name, :field_name, :string, null: false, using: 'field_name::character varying'
    remove_index :table_name, :field_name
  end
end
Related