6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

sqlite3::constraintexception: foreign key constraint failed 【解決策】

Posted at

##起こったこと
ユーザーを削除しようとしたら下記のようなエラーが出てきてしまった。

sqlite3::constraintexception: foreign key constraint failed

##環境
Ruby : 2.7.3
Ruby on Rails : 6.1.3.2
SQLite3 : 3.32.3

##アプリの機能
私が作っているアプリはユーザーが投稿、いいね、コメント、フォロー機能などを備えていました。
ですので、
主なテーブルとして、User,Post テーブル
中間テーブルとして、Postlike,Comment,Relationshipテーブル
を作っていました

##原因・解決策
原因はdependent: :destroyのつけ忘れです。
dependent: :destroyとは、これをモデルにつける(以下のように)ことによってUserが削除された時にUser外部キーに設定していた投稿自体も削除してくれる便利なものです

user.rb
class User < ApplicationRecord
  has_many :posts, dependent: :destroy <---ここが大事
end
post.rb
class Timepost < ApplicationRecord
  belongs_to :user
end

といっても自分自身dependent: :destroyはしっかりコードに記述しながらアプリを作りましたし、再度確認してもしっかりと書かれていたので最初はどこが原因かわかりませんでした。(relationships.rbを除いては)

ユーザーを新規作成し、投稿、いいね機能などを使わずにユーザー削除をすると正常にユーザーは削除されたため、原因はモデル周りにあることははっきりしました。
そして、投稿をした後にユーザー削除をすると正常に削除される(よしよし)、投稿にいいねをした後にユーザー削除をすると正常に削除される(よしよし)、このように1つずつ機能を試し、ユーザー削除が正常に機能しているのかをチェックしていると、フォロー機能を使った後にユーザー削除すると下記のエラーが出ることがわかりました。

sqlite3::constraintexception: foreign key constraint failed

フォロー機能は自分では作り方がわからなかったのでRailsでフォロー機能を作る方法こちらの記事を参考にして作りました。

###見た記事のモデル

user.rb
class User < ApplicationRecord
  has_many :relationships <--ここ
  has_many :followings, through: :relationships, source: :follow
  has_many :reverse_of_relationships, class_name: 'Relationship', foreign_key: 'follow_id' <--ここ
  has_many :followers, through: :reverse_of_relationships, source: :user
end
relationship.rb
class Relationship < ApplicationRecord
  belongs_to :user
  belongs_to :follow, class_name: 'User'

  validates :user_id, presence: true
  validates :follow_id, presence: true
end

問題はuser.rbの2行目と4行目にありました
この2つにdependent: :destroyが記述されておらずエラーが出ていたのです。
ですので以下のコードに変更しました

user.rb
class User < ApplicationRecord
  has_many :relationships, dependent: :destroy  <--ここを変更
  has_many :followings, through: :relationships, source: :follow
  has_many :reverse_of_relationships, class_name: 'Relationship', foreign_key: 'follow_id', dependent: :destroy  <--ここを変更
  has_many :followers, through: :reverse_of_relationships, source: :user
end

###反省
今回はdependent: :destroy のつけ忘れでエラーが出てしまいましたが、根本的な原因はフォロー機能を実装するときにしっかりとコードを理解せず使っていたことです。
初学者のためフォロー機能の作り方なんて思いつきませんし他人のをパクるのはありがと思うのですが自分のアプリで使うコードは最低限理解する必要があるかなと思いました。
これから気をつけたいと思います

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?