rails/rails — pull request #15606 by senny (2014-06-10 13:50:34+00:00)
Title: WIP: Basic support for adding and removing foreign keys

We had this as a GSoC idea but there was no accepted student to work on it. Because I was really looking forward to see this in `rails/rails` I made a first draft.

This patch adds basic support for adding and removing foreign keys using the migration DSL:

```ruby
add_foreign_key :from, :to # will add the key to `to_id`
add_foreign_key :from, :to, column: "fk_id" # with specific column
add_foreign_key :from, :to, dependent: :delete # to specify ON DELETE CASCADE
add_foreign_key :from, :to, name: "my_fk" # with specific name
add_foreign_key :from, :to, primary_key: "special_pk" # will reference `special_pk` from `:to`
```

Removing a foreign key works mostly the same:

```ruby
remove_foreign_key :from, :to # will remove foreign key on `to_id`
remove_foreign_key :from, column: "fk_id" # will remove foreign key on `fk_id`
remove_foreign_key :from, name: "my_fk" # will remove foreign key named `my_fk`
```

Foreign keys are dumped after the indexes to `schema.rb`. The options `name` and `column` are always dumped. `dependent` only when set.

`add_foreign_key` is reversible, `remove_foreign_key` is not.

There is a `connection#supports_foreign_keys?` method to determine wether the adapter does support the API.

### TODO:
- [ ] Write documentation
- [ ] Decide wether `add-/remove_foreign_key` should be no-op when `supports_foreign_keys?` is `false`
- [ ] Support foreign keys when creating a table (work for a different PR but would enable SQLite)

This patch was hugely inspired by `foreigner`. Credits to @matthuhiggins :heart: