Adds foreign key helpers to migrations and correctly dumps foreign keys to schema.rb
Ruby
Switch branches/tags
Nothing to show
Pull request Compare This branch is 5 commits ahead, 110 commits behind matthuhiggins:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
test
.gitignore
.travis.yml
Gemfile
MIT-LICENSE
README.rdoc
Rakefile
foreigner.gemspec

README.rdoc

Foreigner

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:

  • mysql2

  • postgres

  • sqlite (foreign key methods are a no-op)

Installation

Add the following to your Gemfile:

gem 'foreigner'

API Examples

Foreigner adds two methods to migrations.

  • add_foreign_key(from_table, to_table, options)

  • remove_foreign_key(from_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:

add_foreign_key(:comments, :posts)

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.

License

Copyright © 2012 Matthew Higgins, released under the MIT license