ActiveRecord::InvalidForeignKey (Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails (`-app name-_development`.`-Intermediate table name-`, CONSTRAINT `fk_rails_~~~~~` FOREIGN KEY (`-Product table name-_id`) REFERENCES `-Product table name-` (`id`))):
I'm creating a flea market app like Mercari, and I've even implemented a function that allows you to tag and sell products using Form objects. Each model and controller looks like this
/app/model/item.rb
class Item < ApplicationRecord
has_many :tag_item_relations
has_many :tags, through: :tag_item_relations
end
/app/model/tag.rb
class Tag < ApplicationRecord
has_many :tag_item_relations
has_many :items, through: :tag_item_relations
validates :tag_name, uniqueness: true
end
/app/model/tag_item_relation.rb
class TagItemRelation < ApplicationRecord
belongs_to :item
belongs_to :tag
end
/app/form/tags_item.rb
class TagsItem
include ActiveModel::Model
attr_accessor :item_name,
:tag_name
with_options presence: true do
validates :item_name
end
def save
item = Item.create(item_name: item_name)
tag = Tag.where(tag_name: tag_name).first_or_initialize
tag.save
TagItemRelation.create(item_id: item.id, tag_id: tag.id)
end
end
controller
/app/controller/items_controller.rb
class ItemsController < ApplicationController
def index
@items = Item.all.order('created_at ASC')
end
def new
@item = TagsItem.new
end
def create
@item = TagsItem.new(items_params)
if @item.valid?
@item.save
redirect_to root_path
else
render :new
end
end
private
def items_params
params.require(:tags_item).permit(
:item_name,
:tag_name
)
end
end
After that, with the product browsing function Implemented the problem __ product deletion function __
/app/controller/items_controller.rb
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :destroy]
###Omission
def show
@tags_item = TagItemRelation.find(params[:id])
end
def destroy
if current_user.id == @item.user_id
@item.destroy
redirect_to root_path
else
render :show
end
end
private
###Omission
def set_item
@item = Item.find(params[:id])
@tag = Tag.find(params[:id])
end
end
However, when I try to delete the items that I actually put up, ...
ActiveRecord::InvalidForeignKey (Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails (`-app name-_development`.`tag_item_relations`, CONSTRAINT `fk_rails_~~~~~~` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`))):
Error occurred and the product could not be deleted.
If you read the error details carefully, the product id is included in the __foreign key __ of the intermediate table. I can't delete or update! You can see that it is written
So when I looked up foreign keys ... Foreign keys (also known as foreign constraint keys) are database keys that are often written in migration files, etc. It prevents you from entering arbitrary values in specific items in the database, and has restrictions to select from external items. It seems that it mainly restricts __changes from the foreign key table to the data in the primary key table. In this case, you can see that the foreign key table is tag_item_relations and the primary key table is item.
The cause of this error was the foreign key (foreign_key: true) described in the migration file. However, if you rewrite the entire migration file, another problem may occur. This time I'm going to set dependent:: destroy to delete the item set as a foreign key in destory With this simple setting, you will be able to delete products without any problems.
/app/model/item.rb
class Item < ApplicationRecord
has_many :tag_item_relations, foreign_key: :item_id, dependent: :destroy
has_many :tags, through: :tag_item_relations
end
What is a foreign key? (https://wa3.i-3-i.info/word1992.html)
Because I was addicted to foreign key constraints (rails) Settings for destroying data with foreign keys
Recommended Posts