Add a reference column migration in Rails 4 Add a reference column migration in Rails 4 ruby-on-rails ruby-on-rails

Add a reference column migration in Rails 4


Rails 4.x

When you already have users and uploads tables and wish to add a new relationship between them.

All you need to do is: just generate a migration using the following command:

rails g migration AddUserToUploads user:references

Which will create a migration file as:

class AddUserToUploads < ActiveRecord::Migration  def change    add_reference :uploads, :user, index: true  endend

Then, run the migration using rake db:migrate.This migration will take care of adding a new column named user_id to uploads table (referencing id column in users table), PLUS it will also add an index on the new column.

UPDATE [For Rails 4.2]

Rails can’t be trusted to maintain referential integrity; relational databases come to our rescue here. What that means is that we can add foreign key constraints at the database level itself and ensure that database would reject any operation that violates this set referential integrity. As @infoget commented, Rails 4.2 ships with native support for foreign keys(referential integrity). It's not required but you might want to add foreign key(as it's very useful) to the reference that we created above.

To add foreign key to an existing reference, create a new migration to add a foreign key:

class AddForeignKeyToUploads < ActiveRecord::Migration  def change    add_foreign_key :uploads, :users  endend

To create a completely brand new reference with a foreign key(in Rails 4.2), generate a migration using the following command:

rails g migration AddUserToUploads user:references

which will create a migration file as:

class AddUserToUploads < ActiveRecord::Migration  def change    add_reference :uploads, :user, index: true    add_foreign_key :uploads, :users  endend

This will add a new foreign key to the user_id column of the uploads table. The key references the id column in users table.

NOTE: This is in addition to adding a reference so you still need to create a reference first then foreign key (you can choose to create a foreign key in the same migration or a separate migration file). Active Record only supports single column foreign keys and currently only mysql, mysql2 and PostgreSQL adapters are supported. Don't try this with other adapters like sqlite3, etc. Refer to Rails Guides: Foreign Keys for your reference.


Rails 5

You can still use this command to create the migration:

rails g migration AddUserToUploads user:references

The migration looks a bit different to before, but still works:

class AddUserToUploads < ActiveRecord::Migration[5.0]  def change    add_reference :uploads, :user, foreign_key: true  endend

Note that it's :user, not :user_id


if you like another alternate approach with up and down method try this:

  def up    change_table :uploads do |t|      t.references :user, index: true    end  end  def down    change_table :uploads do |t|      t.remove_references :user, index: true    end  end