前提・実現したいこと
ユーザーをデータベースから削除しようとしましたが、「Invalid Foreign Key」のエラーが出て削除が出来ません。
ユーザーはUser
テーブルを介して、他の複数のテーブルと「多対多」ないし「1対多」の関係で結びついています。
調べてみた所、以下の内容が原因かと思いました。
「該当のユーザーが削除された際に、例えばユーザーの主キーを参照する他テーブルのデータは参照先を持たないデータとなってしまう。」
ですので全てのテーブルに関して、has_many
(ないしhas_one
)に対してdependent: :destroy
の書き忘れがないかを見直し、ない部分には書き足しました。
しかし該当のエラーが変わらず出てきます…。どのように対応すれば宜しいでしょうか。
ご助言を頂けますと有難いです。
発生している問題・エラーメッセージ
[12] pry(main)> User.find(20).destroy ... #省略。該当のユーザーが関わっているアソシエーション関連の情報の読み込み。 ActiveRecord::InvalidForeignKey: SQLite3::ConstraintException: FOREIGN KEY constraint failed: DELETE FROM "users" WHERE "users"."id" = ? from C:/Users/hoge/vendor/bundle/ruby/2.6.0/gems/sqlite3-1.4.2/lib/sqlite3/statement.rb:108:in `step' Caused by SQLite3::ConstraintException: FOREIGN KEY constraint failed from C:/Users/hoge/vendor/bundle/ruby/2.6.0/gems/sqlite3-1.4.2/lib/sqlite3/statement.rb:108:in `step'
試したこと
-
試しにユーザーを新規作成し、何のアクションもしないままユーザーの削除を試みると上手く削除出来ました。
-
本アプリにはフォロー、投稿、コメント、いいね、メッセージ、通知機能などあるのですが、何かしらのアクションを起こした(また他ユーザーから起こされた)後だと削除が出来なくなります。やはり外部キーに問題があるようです。
-
「ある該当のアクションを行うとユーザーの削除が出来なくなる」のではなく「基本的に何でもアクションを行う(される)と削除が出来なくなる」現象が起こっています。
あらゆるアクションに共通して絡んでいるのは通知機能であるNotifications
テーブルですので、こちらが怪しいのではと踏んだのですが、以下の理由からそれもどうやら違うようです。
メッセージ機能において、ユーザーがトークルーム(Room
, Entry
テーブル)を作成するアクションがあってからメッセージのやり取りが出来るようになるのですが、このアクション自体は相手に通知がいきません。
試しに「新規ユーザーA」を作成し、他のユーザーが「ユーザーA」とのトークルームを作った(メッセージの送信はしていない)段階で「ユーザーA」の削除を試みました(ユーザーAは何のアクションもしていない)。
しかしこれでも削除が出来なかったので、通知が絡んでいる・いないは関係ないようです…。
4. 最後にモデルの関連付けを全てコメントアウトしてからユーザーの削除を試みましたが、それでも全く同じエラーが出ました。
補足情報(FW/ツールのバージョンなど)
ruby 2.6.4p104
RubyGems 3.0.3
Rails 5.2.3
追記
rails db:schema:dump
を行いschema.rb
を最新のものにしました。
また追記により文字数制限を超えてしまったので、前回載せていた古い方のschema.rb
を削除しました。
C:\Users\hoge\app\アプリ名>rails db:schema:dump (0.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC ↳ bin/rails:4
schema.rb
ActiveRecord::Schema.define(version: 2021_01_08_054626) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false t.integer "record_id", null: false t.integer "blob_id", null: false t.datetime "created_at", null: false t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end create_table "active_storage_blobs", force: :cascade do |t| t.string "key", null: false t.string "filename", null: false t.string "content_type" t.text "metadata" t.bigint "byte_size", null: false t.string "checksum", null: false t.datetime "created_at", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end create_table "comments", force: :cascade do |t| t.integer "user_id" t.integer "post_id" t.text "body" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "entries", force: :cascade do |t| t.integer "user_id" t.integer "room_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["room_id"], name: "index_entries_on_room_id" t.index ["user_id"], name: "index_entries_on_user_id" end create_table "goings", force: :cascade do |t| t.integer "user_id" t.integer "post_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "languages", force: :cascade do |t| t.string "description" t.boolean "done" t.integer "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["user_id"], name: "index_languages_on_user_id" end create_table "likes", force: :cascade do |t| t.integer "user_id" t.integer "post_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "messages", force: :cascade do |t| t.integer "user_id" t.integer "room_id" t.text "content" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["room_id"], name: "index_messages_on_room_id" t.index ["user_id"], name: "index_messages_on_user_id" end create_table "notifications", force: :cascade do |t| t.integer "visitor_id", null: false t.integer "visited_id", null: false t.integer "post_id" t.string "action", default: "", null: false t.boolean "checked", default: false, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "comment_id" t.integer "message_id" t.integer "room_id" t.boolean "read", default: false, null: false t.index ["comment_id"], name: "index_notifications_on_comment_id" t.index ["message_id"], name: "index_notifications_on_message_id" t.index ["post_id"], name: "index_notifications_on_post_id" t.index ["room_id"], name: "index_notifications_on_room_id" t.index ["visited_id"], name: "index_notifications_on_visited_id" t.index ["visitor_id"], name: "index_notifications_on_visitor_id" end create_table "posts", force: :cascade do |t| t.string "title" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "user_id" t.string "message" t.string "level" t.integer "maximum" t.string "post_image_name" t.string "language" t.date "date" t.time "time" t.datetime "closing_time" end create_table "relationships", force: :cascade do |t| t.integer "follower_id" t.integer "following_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["follower_id", "following_id"], name: "index_relationships_on_follower_id_and_following_id", unique: true t.index ["follower_id"], name: "index_relationships_on_follower_id" t.index ["following_id"], name: "index_relationships_on_following_id" end create_table "rooms", force: :cascade do |t| t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "user_languages", force: :cascade do |t| t.integer "user_id" t.integer "language_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["language_id"], name: "index_user_languages_on_language_id" t.index ["user_id"], name: "index_user_languages_on_user_id" end create_table "users", force: :cascade do |t| t.string "name" t.string "email" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "image_name" t.string "password_digest" t.string "cover_image_name" t.string "sex" t.string "country" t.string "language" t.text "introduction" end end
回答1件
あなたの回答
tips
プレビュー