前提
progamesテーブルとchatroomsテーブルが1対1の関係。(progamesテーブルがchatroomsテーブルを持っている。)
発生しているエラー
SQL文のdeleteメソッドでpro_gamesテーブルのレコードを全て削除しようとすると以下のエラーが発生。
Cannot delete or update a parent row: a foreign key constraint fails
解決
先に親を消しているのが原因。子を先に消しておくとうまくいく。
(今回の場合だとchatroomsテーブルから消しておく。)
なぜ親からだと削除できない??
モデルにdependent: :destroy
を書いているのになぜ削除できない??
class ProGame < ApplicationRecord
has_one :chatroom, dependent: :destroy
end
原因発覚
SQL文で削除しようとしたことが原因。
resources :pro_games, only: [:create]
destroyメソッドはモデルを介するので、dependent: :destroyが効く。しかしdeleteメソッドはモデルを解さない。よってモデルに記載したdependent: :destroy
が効かなかった。
deleteメソッドとdestroyメソッドの違い
delete
メソッド(またはdelete_all
)はモデルを介さず直接SQL文をDBに送る。
destroy
メソッド(destroy_all
)はモデルを介してSQL文を送る。
delete、delete_all、destroy、destroy_allメソッドについてはこちらの記事(https://qiita.com/kamelo151515/items/0fa7fb15a1d2c1e44db2)。
まとめ
よって次から削除するときはdestoryメソッドでモデルを経由して削除するか、先に子を消すように意識する。
参考にした記事
#1451 - Cannot delete or update a parent row: a foreign key constraint fails の解決法