【问题标题】:I have this problem in Ruby on Rails SQLite3::ConstraintException: FOREIGN KEY constraint failed我在 Ruby on Rails SQLite3::ConstraintException: FOREIGN KEY constraint failed 中有这个问题
【发布时间】:2021-03-20 17:50:34
【问题描述】:

我是 Ruby on Rails 的新手。我尝试制作标签并可以选择删除标签。当我想销毁标签时,我收到此错误 SQLite3::ConstraintException: FOREIGN KEY constraint failed.

ActiveRecord::InvalidForeignKey in TagsController#destroy

这是我在控制器中删除标签的代码:

def destroy
    @tag = Tag.find(params[:id])
    @tag.destroy

    flash.notice = "Tag '#{@tag.name}' Deleted!"
    
    redirect_to tags_path
end

这是 schema.rb

ActiveRecord::Schema.define(version: 2021_03_20_115719) do

  create_table "articles", force: :cascade do |t|
    t.string "title"
    t.text "body"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "comments", force: :cascade do |t|
    t.string "author_name"
    t.text "body"
    t.integer "article_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["article_id"], name: "index_comments_on_article_id"
  end

  create_table "taggings", force: :cascade do |t|
    t.integer "tag_id", null: false
    t.integer "article_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["article_id"], name: "index_taggings_on_article_id"
    t.index ["tag_id"], name: "index_taggings_on_tag_id"
  end

  create_table "tags", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  add_foreign_key "comments", "articles"
  add_foreign_key "taggings", "articles"
  add_foreign_key "taggings", "tags"
end

【问题讨论】:

  • 您需要为Tag 发布您的schema.rb 资料。很可能您在另一个表中设置了一个约束来引用 Tag
  • @ChristopherOezbek 我用模式填写问题。提前致谢

标签: ruby-on-rails ruby


【解决方案1】:

FOREIGN KEY 约束失败通常意味着您的数据库中有另一条记录仍然有一个belongs_to 关联设置到该记录,因此您不能删除它。

在您的示例中,有一个article 带有您要删除的标签。

create_table "taggings", force: :cascade do |t|
  t.integer "tag_id", null: false        # << here the association
  t.integer "article_id", null: false

# in combination with

add_foreign_key "taggings", "articles"
add_foreign_key "taggings", "tags"       # << here the foreign key constraint

您的schema.rb 表明您有一个taggings 连接表,该表将文章与标签连接起来,在此表中,两个属性(tag_idarticle_id)都不能是nil,并且必须包含一个有效的标识关联表上的记录的 id。

这意味着当您想要删除特定标签时,您必须首先从taggings 连接表中删除该标签。以下代码应该可以工作:

def destroy
  @tag = Tag.find(params[:id])
  @tag.articles.clear                    # << add this line
  @tag.destroy

  flash.notice = "Tag '#{@tag.name}' Deleted!"

  redirect_to tags_path
end

Rails Guides 中了解collection.clearhas_and_belongs_to 关联的一般用法。

【讨论】:

  • 谢谢@spickermann。我用 schema.rb 代码填写了我的问题
  • @MarcMarc 我在阅读您的数据库架构后更新了我的答案,以便为您的问题提供更具体的解决方案。
  • 非常感谢@spickermann。这对我有帮助,现在可以了。
猜你喜欢
  • 2019-12-04
  • 1970-01-01
  • 2020-08-07
  • 2018-06-10
  • 2022-08-22
  • 2013-11-20
  • 1970-01-01
  • 2019-11-14
  • 2014-01-02
相关资源
最近更新 更多