What New With Foreign Keys in Rails 4.2?

Apr 16th, 2015

Previous versions of Rails did not have the ability to create foreign keys without resorting to executing SQL statements directly. This lead to messy, database dependent solutions that weren’t very nice.

Luckily, Rails 4.2 rectifies this with new features to add and remove foreign keys. In this article we will discuss what foreign keys are, and how to add them to your database.

If you don’t know what a foreign key is, well, quite simply, a foreign key links one table to another’s primary key. For example, if I have an authors table and a books table, I could create a foreign key that points from books back to authors, linking the two tables together. Then, these two tables become linked. It means that I cannot add or update the record with invalid data for the author_id field in the books table. I can also tell the database server what to do when I update or delete the record. For example, I can tell rails to automatically delete child records when the parent is deleted (delete an author from the authors table and all the author’s books are deleted). I could also tell Rails to set the author_id column to null or to simply not let me delete the author while child records exist.

Add Foreign Keys
To add a foreign key to the books table:

1

add_foreign_key:books,:authors

We can also give the foreign key a custom name:

1

add_foreign_key:books,:authors,name::my_foreign_key

If we are using a non Rails friendly database, we can specify the column names we wish to use for the foreign key. For example, let’s say the primary key of the authors table is author_id and the key in the books table is auid. We could simply use the following code to create the foreign key:

1

add_foreign_key:books,:authors,column::auid,primary_key::author_id

We can control the behavior of the foreign key as well. A list of the available behaviors are below. Independent behaviors can be set for both update as well as delete.
- :restrict (default) - Prevents changes from being made.
- :nullify - Sets the child columns to null.
- :cascade - Cascades down to the child records. For instance, deleting an author deletes the author’s books.

To specify behaviors, you simply use the on_delete or on_update parameters. For example, the following code would cascade deletes so that the books get deleted when the parent gets deleted.

1

add_foreign_key:books,:authors,on_delete:cascade

Delete Foreign Keys
It is just as easy to delete foreign keys:

1

remove_foreign_key:books,:authors

You can optionally specify the name of the foreign key to delete:

1

remove_foreign_key:books,name::my_foreign_key

If you have non Rails friendly column names, you can specify the column name that contains the foreign key you wish to remove: