RoR:数据库级参照完整性

RoR: database level referential integrity

我有这个型号:

class Book < ApplicationRecord
  has_many :pages, dependent: :destroy
end

还有这个:

class Page < ApplicationRecord
  belongs_to :book
end

Book 的迁移是:

class CreateBooks < ActiveRecord::Migration[5.0]
  def change
    create_table :books do |t|
    end
  end
end

Page 的迁移是:

class CreatePages < ActiveRecord::Migration[5.0]
  def change
    create_table :pages do |t|
      t.references :book, index: true, null: false
    end
  end
  add_foreign_key :pages, :books, on_delete: :cascade
end

另外我得到了一些种子:

Book.create!(
  pages: [
    Page.new,
    Page.new,
    Page.new
  ]
)

rake db:migraterake db:seed 和所有爵士乐。我跳进 rails c:

Book.first
Book Load (0.1ms)  SELECT  "books".* FROM "books" ORDER BY "books"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<Book id: 1>

酷....现在?

Page.count
(0.3ms)  SELECT COUNT(*) FROM "pages"
=> 3

完全有道理。下一篇:

Book.first.destroy
Book Load (0.2ms)  SELECT  "books".* FROM "books" ORDER BY "books"."id" ASC LIMIT ?  [["LIMIT", 1]]
(0.1ms)  begin transaction
Page Load (0.1ms)  SELECT "pages".* FROM "pages" WHERE "pages"."book_id" = ?  [["book_id", 1]]
SQL (0.1ms)  DELETE FROM "pages" WHERE "pages"."id" = ?  [["id", 1]]
SQL (0.0ms)  DELETE FROM "pages" WHERE "pages"."id" = ?  [["id", 2]]
SQL (0.0ms)  DELETE FROM "pages" WHERE "pages"."id" = ?  [["id", 3]]
SQL (0.1ms)  DELETE FROM "books" WHERE "books"."id" = ?  [["id", 1]]

耶!快到了......再次播种后我这样做:

Book.first.delete
Book Load (0.1ms)  SELECT  "books".* FROM "books" ORDER BY "books"."id" ASC LIMIT ?  [["LIMIT", 1]]
SQL (144.0ms)  DELETE FROM "books" WHERE "books"."id" = ?  [["id", 2]]

卧槽?

Page.count
(0.1ms)  SELECT COUNT(*) FROM "pages"
=> 3

我知道delete不会触发回调,所以dependent: :destroy在这里帮不了我。但是外键呢?你好?我想要我的数据库级别的参照完整性!!我究竟做错了什么?我尝试了更多的东西,比如将 on_delete: :cascade 移动到字段定义中:

def change
  create_table :pages do |t|
    t.references :book, index: true, null: false
  end
end

但是...不,结果相同。我已经搜索并阅读了两次 ActiveRecord 文档,SO 中的其他一些问题将我指向了我当前的设置(这不是我正在处理的项目,而是一个新生成的具有相同基本配置的复制错误 - 是的,它也在那里失败了),但我无法指出问题所在。也许为时已晚,我太累了。帮助? Rails 甚至支持这个吗?我正在使用 v5,远远领先于 4.2,其中集成了数据库级别的约束。我的 db/schema.rb 看起来像这样:

ActiveRecord::Schema.define(version: 20160218232358) do

  create_table "books", force: :cascade do |t|
  end

  create_table "pages", force: :cascade do |t|
    t.integer "book_id", null: false
    t.index ["book_id"], name: "index_pages_on_book_id"
  end

end

没有外键的痕迹?

因为你正在测试你可能正在使用 SQLite,这里只提到 mysql、mysql2 和 postgres 因此我认为 rails 不支持SQLite 上的外键:http://edgeguides.rubyonrails.org/4_2_release_notes.html#foreign-key-support

在另一个中也有这样的表述post: