Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails InvalidForeignKey

I am developing a portfolio for my website, I decided to add skills to each portfolio item.

class PortfolioSkill < ApplicationRecord
  belongs_to :portfolio
  belongs_to :skill
end

class Portfolio < ApplicationRecord

  has_many :portfolio_skills
  has_many :skills, through: :portfolio_skills


  def all_tags=(names)
    self.skills = names.split(",").map do |name|
      Skill.where(name: name.strip).first_or_create!
  end
end

 def all_tags
  self.skills.map(&:name).join(", ")
 end

 def remove_skill_tags
    PortfolioSkill.where(portfolio_id: id).destroy_all
 end


end



 create_table "portfolio_skills", force: :cascade do |t|
     t.integer "portfolio_id"
     t.integer "skill_id"
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.index ["portfolio_id"], name:     "index_portfolio_skills_on_portfolio_id"
     t.index ["skill_id"], name: "index_portfolio_skills_on_skill_id"
  end

create_table "portfolios", force: :cascade do |t|
    t.string "name"
    t.string "client"
    t.date "completed"
    t.text "about"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "long_landscape"
    t.string "cover"
    t.integer "category_id"
    t.index ["category_id"], name: "index_portfolios_on_category_id"
  end

When I click destroy on the index page I get the

SQLite3::ConstraintException: FOREIGN KEY constraint failed: DELETE FROM "portfolios" WHERE "portfolios"."id" = ?

error. All the associations look right. I used this same pattern for my tags on other models and it worked with no issues. Any help would be great.

like image 724
John Avatar asked Dec 18 '22 07:12

John


1 Answers

You are deleting from portfolios table, but table portfolio_skills has a column referencing it as foreign key. Hence the error.

Trying to delete a parent without checking and deleting its associated children can lead to data inconsistency. This exception is in place to prevent that.

Rails dependent destroy will take care of removing associated children rows while removing a parent.

Try using a dependent destroy:-

class Portfolio < ApplicationRecord
  has_many :portfolio_skills, :dependent => :destroy
  ...
end
like image 168
rohan Avatar answered Dec 26 '22 21:12

rohan