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:migrate
、rake 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:
我有这个型号:
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:migrate
、rake 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: