【发布时间】:2016-06-19 06:52:49
【问题描述】:
article_id 必须在图片表中,因为每篇文章可以有很多图片。
所以图片表看起来像这样:
id article_id picture
1 34 pinguin.jpg
2 56 koala.jpg
3 56 bear.jpg
等
我知道destroy_all(在依赖表上实例化一个对象并调用它的destroy方法,这是一个缓慢的过程)和delete_all之间的区别,它只是清除记录而不关心关联。
但我必须使用 destroy_all 因为有相关的依赖记录:
Article Model
class Article < ActiveRecord::Base
belongs_to :user
has_many :pictures , **`dependent: :destroy`**
accepts_nested_attributes_for :pictures
Picture Model
class Picture < ActiveRecord::Base
belongs_to :article
mount_uploader :picture, PictureUploader
def destroy
end
架构
create_table "articles", force: :cascade do |t|
t.string "country"
t.string "region"
t.string "town"
t.string "street"
t.string "company"
t.string "title"
t.text "content"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "articles", ["user_id", "created_at"], name: "index_articles_on_user_id_and_created_at", using: :btree
add_index "articles", ["user_id"], name: "index_articles_on_user_id", using: :btree
create_table "pictures", force: :cascade do |t|
t.integer "article_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "picture"
end
所以,Article.delete_all 和 Article.destroy_all 这两个命令
提出类似的投诉
Article.destroy_all
Article Load (0.9ms) SELECT "articles".* FROM "articles" ORDER BY "articles"."created_at" DESC
(0.1ms) BEGIN
SQL (1.7ms) DELETE FROM "articles" WHERE "articles"."id" = $1 [["id", 21]]
PG::ForeignKeyViolation: ERROR: update or delete on table "articles" violates foreign key constraint "fk_rails_658164416e" on table "pictures"
DETAIL: Key (id)=(21) is still referenced from table "pictures".
: DELETE FROM "articles" WHERE "articles"."id" = $1
(0.2ms) ROLLBACK
class CreatePictures < ActiveRecord::Migration
def change
create_table :pictures do |t|
t.references :article, index: true, foreign_key: true
t.timestamps null: false
end
end
end
更新
我已尝试在迁移文件中添加 on delete 级联 FK,但无济于事:
我首先删除了 FK,因为我必须添加限定符:on_delete: :cascade
class RemoveFkFromPictures < ActiveRecord::Migration
def change
remove_foreign_key :pictures, column: :article_id
end
end
我创建了另一个迁移文件来添加 FK
class AddForeignKeyToPictures1 < ActiveRecord::Migration
def change
add_foreign_key :pictures, :articles, on_delete: :cascade , name: :deletingarticlescascadesonpictures
end
end
架构看起来像:
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_foreign_key "articles", "users"
add_foreign_key "pictures", "articles", name: "deletingarticlescascadesonpictures", on_delete: :cascade
end
所以,你会认为现在没问题。好吧,它不是:
Article Load (1.3ms) SELECT "articles".* FROM "articles" ORDER BY "articles"."created_at" DESC
(0.2ms) BEGIN
Picture Load (0.5ms) SELECT "pictures".* FROM "pictures" WHERE "pictures"."article_id" = $1 [["article_id", 25]]
(0.4ms) ROLLBACK
ActiveRecord::RecordNotDestroyed: Failed to destroy the record
【问题讨论】:
-
那些**不在你的模型中,你只是用它们来突出显示。您可以创建一个在 rails 中级联删除的 fk。一切都取决于您是否希望 rails 删除它或数据库。
-
您需要自己编写迁移代码。生成器不会为您执行此操作。
-
在迁移中使用 remove_foreign_key 然后 add_foreign_key 来改变它。您也可以使用 execute 在那里运行您自己的 SQL
-
已确认。那还没有解决问题。我重置了整个数据库,删除了迁移文件。删除外键,检查外键首先存在的架构文件(没有 on delete 级联),然后创建另一个迁移添加 on_delete 级联,如下所示: add_foreign_key :pictures, :articles, on_delete: :cascade 架构文件清楚地显示了更改并显示了以下信息: add_foreign_key "articles", "users" add_foreign_key "pictures", "articles", on_delete: :cascade end 然后我尝试删除并得到错误:未能销毁记录。
标签: ruby-on-rails