Reputation: 139
I am new to Ruby on Rails. I try to make tags and have the option to delete the tag. When I want to destroy the tag, I get this error SQLite3::ConstraintException: FOREIGN KEY constraint failed.
ActiveRecord::InvalidForeignKey in TagsController#destroy
Here are my code for delete tag in controller:
def destroy
@tag = Tag.find(params[:id])
@tag.destroy
flash.notice = "Tag '#{@tag.name}' Deleted!"
redirect_to tags_path
end
This is the 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
Upvotes: 5
Views: 3185
Reputation: 106792
A failed FOREIGN KEY constraint usually means that you have another record in your database that still has a belongs_to
association set to this record and therefore you cannot delete it.
In your example, there is an article
tagged with the tag you are trying to delete.
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
Your schema.rb
shows that you have a taggings
join table that connects articles with tags and in this table, both attributes (the tag_id
and the article_id
) cannot be nil
and must contain a valid id that identifies a record on the associated table.
That means when you want to delete a specific tag then you have to remove the tag from the taggings
join table first. The following code should work:
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
Read about collection.clear
and the usage of the has_and_belongs_to
association in general in the Rails Guides.
Upvotes: 11