Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a reference column migration in Rails 4

A user has many uploads. I want to add a column to the uploads table that references the user. What should the migration look like?

Here is what I have. I'm not sure if I should use (1) :user_id, :int or (2) :user, :references. I'm not even sure if (2) works. Just trying to do this the "rails" way.

class AddUserToUploads < ActiveRecord::Migration   def change     add_column :uploads, :user_id, :integer   end end 

Relevant question except for Rails 3. Rails 3 migrations: Adding reference column?

like image 494
Don P Avatar asked Apr 02 '14 14:04

Don P


People also ask

How do I add a reference column in rails?

When you already have users and uploads tables and wish to add a new relationship between them. 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.


2 Answers

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   end end 

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   end end 

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   end end 

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.

like image 169
Kirti Thorat Avatar answered Oct 29 '22 02:10

Kirti Thorat


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   end end 

Note that it's :user, not :user_id

like image 38
Mirror318 Avatar answered Oct 29 '22 02:10

Mirror318