Rails 4.2 からの DB Migration は FK を標準でサポートする予定になっていますが、現時点では、多くの方が foreigner を使っている状況かと思います。
foreigner は SQLite3 の場合は処理をスキップするようになっています。
これは、まあ以下の issue でも回答されている通り、妥当なところではあって
SQLite3 はデフォルトでは off の pragma を有効にすれば FK を使うことも出来るのですが
SQLite3 は以下に明記されている通り
alter table の構文では、何と add column くらいしかまともにサポートしていないという状況で、他の RDBMS のように add constraint することができず、テーブルの再作成が必要になってしまいます。
実際、ActiveRecord の sqlite3_adapter に #remove_column が実装されていますが、こんな感じの力技です。
[1] pry(main)> ActiveRecord::Base.connection.remove_column("user", "company_id")
(0.1ms) begin transaction
(1.1ms) CREATE TEMPORARY TABLE "auser" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "company_id" integer NOT NULL, "created_at" datetime NOT NULL)
(0.5ms) SELECT * FROM "user"
(1.1ms) DROP TABLE "user"
(0.2ms) CREATE TABLE "user" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime NOT NULL)
(0.1ms) SELECT * FROM "auser"
(0.3ms) DROP TABLE "auser"
(0.9ms) commit transaction
=> []
そんな感じなので、ほとんどの方は MySQL なり PostgreSQL を development や test でも使えばいいじゃんというスタンスだと思うし、実際わざわざ違う RDBMS で動かす必要もないのですが、とはいえ、SQLite3 の手軽さは、デザイナーとの協業やら、普段触ってないプロジェクトをちょっと起動するときやら、CI の設定をするときやら、いろんなケースで嬉しいというのもまた事実です。
できれば FK を使った DB 設計のテストでも SQLite3 を使えないものか。ということで foreigner の SQLite3 で動作する adapter を実装してみました。
最初は ActiveRecord の remove_column とか使っていましたが、テーブル再作成するタイミングで元々ある FK の設定が失われてしまうため、sqlite_master テーブルから create table の DDL をとってきて置換するようにしました。
元々データがある時の扱いが結構厄介なのですが、とりあえずそういうケースでは標準出力に warning を出して foreigner と同様スキップしています。この辺は私は今すぐ必要とはしていないのですが、うまく実装できれば対応したいところです。
追記:2015/12
Rails 4.2 からは foreigner が存在すると正常に動作しなくなっています。
http://qiita.com/seratch@github/items/4cccda08f8ba96ac6173