Migrating a column to foreign key and foreign table

I’m attempting to write a migration that adds a foreign key column to
a table to replace an existing attribute (a string to an object). I’d
like to add the column, convert the existing data into a new entry on
the foreign table and then set the foreign key value.

I’m successfully able to add the column, but it doesn’t seem like the
objects mapped to the foreign table get created, as after the
migration completes the foreign table is empty and the foreign key
values are very large, seemingly random integers.

I’ve tried doing Object.new + Object.save and Object.create, but
neither seems to work. I’ve also tried both of those inside of a
transaction within the ‘self.up’ that’s marked as ‘:requires_new’.

Any thoughts on what I might be doing wrong or how to debug this? Any
links to examples?

Thanks.

Nathan B. wrote:

I’m attempting to write a migration that adds a foreign key column to
a table to replace an existing attribute (a string to an object). I’d
like to add the column, convert the existing data into a new entry on
the foreign table and then set the foreign key value.

I’m successfully able to add the column, but it doesn’t seem like the
objects mapped to the foreign table get created, as after the
migration completes the foreign table is empty and the foreign key
values are very large, seemingly random integers.

I’ve tried doing Object.new + Object.save and Object.create, but
neither seems to work. I’ve also tried both of those inside of a
transaction within the ‘self.up’ that’s marked as ‘:requires_new’.

Any thoughts on what I might be doing wrong or how to debug this? Any
links to examples?

Thanks.

From your project type:

script/generate migration AddForeignKeyColumnToTableName
… or if windows …
ruby script/generate migration AddForeignKeyColumnToTableName

The name of the migration can be anything. I like to use Capitalized
letters for each new word to describe what I’m doing the migration for.
In the case above, a migration file will be named
add_foreign_key_column_to_table_name in your migrations folder.

Go to your database migrations “migrations” folder and open the new
migration we just created so you can edit it.

def self.up
add_column :table, :key_id, :integer

@model = Model.find(:all)
@model.each do |model|
model.update_attribute(:key_id, model.column_name_to_convert)
end

end

def self.down
remove_column :table, :key_id
end

This should get you close to what you are after. What we are going to
replace in this code are the following:

key_id = the name of the foreign_id you want to name your column
table = the name of your table (pluralized)
model = the name of the model you are querying to convert the key for.
column_name_to_convert = the name of the column you are using to convert
data from to the new key_id column.

After you do this, it will perform the following, in order:

Add your foreign_key column to your model’s table.
Find all records in your model.
Iterate through all records in your model.
Change the data for key_id with the data for column_name_to_convert’s
data.

Make sure the types match. If you are converting from a string you need
to use .to_i, etc.

Hopefully, this works. It should at first glance.

Also, one other note. I wouldn’t remove the column you are migrating
data from until you confirm that the data was migrated. Therefore, you
would remove the old column after the first one succeeded by performing
a separate migration.

I hope that helps.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs