Foreigner introduces a few methods to your migrations for adding and removing foreign key constraints. It also dumps foreign keys to schema.rb.
The following adapters are supported:
sqlite (foreign key methods are a no-op)
Add the following to your Gemfile:
Foreigner adds two methods to migrations.
add_foreign_key(from_table, to_table, options)
(Options are documented in connection_adapters/abstract/schema_definitions.rb):
For example, given the following model:
class Comment < ActiveRecord::Base belongs_to :post end class Post < ActiveRecord::Base has_many :comments, dependent: :delete_all end
You should add a foreign key in your migration:
The :dependent option can be moved from the has_many definition to the foreign key:
add_foreign_key(:comments, :posts, dependent: :delete)
If the column is named article_id instead of post_id, use the :column option:
add_foreign_key(:comments, :posts, column: 'article_id')
A name can be specified for the foreign key constraint:
add_foreign_key(:comments, :posts, name: 'comment_article_foreign_key')
If you have foreign keys that are enforced against unique columns that are not Rails id columns and may be updated, and your Foreigner adapter supports it, you should use dependent: :cascade. This cascades both deletes and updates:
add_foreign_key(:people, :salutation, :column: :salutation_value, :primary_key: :salutation_value, :dependent: :cascade
This way if you change a salutation (e.g., Rev to Reverend) the change will cascade into the people table.
Currently the SQL2003 adapters (PostgreSQL and Mysql2) support creating such FKs, but only PG reflects them. The foreigner-sqlserver gem also works both ways.
Finally, some adapters may support :dependent :default, which affects the delete behaviour while still cascading updates. Use the source, Luke!
Change Table Methods
Foreigner adds extra methods to change_table.
Add a missing foreign key to comments:
change_table :comments do |t| t.foreign_key :posts, dependent: :delete end
Remove an unwanted foreign key:
change_table :comments do |t| t.remove_foreign_key :users end
Finding Missing Foreign Keys
Use Immigrant to generate a migration that includes all missing foreign keys.
Copyright © 2012 Matthew Higgins, released under the MIT license