こちらはcategories_peopleテーブルに存在する外部キー制約によりpeopleテーブルのデータが削除できないというエラーになります。
まず、外部キー制約について説明します。
今回のpeopleとcategories_peopleのような1対多になるテーブル関係では、1側(今回ではpeopleのデータ)が削除されてしまうと、場合によっては、多側(今回ではcategories_people)のデータが二度と使われないことがあります。
二度と使われないデータが残ってしまうのは、リソース上不都合があります。
そうしたデータが残されることを避けるために、外部キー制約というSQLの機能が存在します。
以下は具体例です。
仮にpeopleに以下のデータがあったとします。
people = {id: 1, name: '太郎', age: '20'}
そしてpeoples_categoryには以下のデータそれぞれがあります。
peoples_category1 = {people_id: 1, category_id: 1}
peoples_category2 = {people_id: 1, category_id: 2}
peoples_category3 = {people_id: 1, category_id: 3}
この時、people(太郎のデータ)を削除しようとして、削除に成功したとします。
すると、peoples_category1〜3のデータは、
太郎のデータはもう削除してしまったので、
太郎のデータからは二度と検索されなくなります。
なので、もし開発しているアプリケーション上で、
必ず太郎などのpeopleのデータからpeoples_categoryのデータを検索している場合、
二度と検索されない不要なデータが、知らない間に残されてしまいます。
それは困ってしまうので、外部キー制約を設けることで、回避することができます。
データの扱いについて3種類の外部キー制約を選ぶことができます。
(Railsを通してtableを作らなければ、外部キー制約自体をなくすこともできますが、ここでは割愛します。)
- エラーとして知らせる(今回のケース)
- 不要なデータをデータベース管理機能が判断して自動的に消す
- 1側のデータとの接続を削除するが、多側のデータ自体は削除しない
Railsは、デフォルトでは1の外部キー制約が影響してしまうために、削除できないというエラーが出てしまいます。
ですが、以下のリンク先の方法で、2や3の方法も選択することができます。
dependent オプション
has_manyにdependentオプションをつけることで、このエラーを回避できます。
:destroy, :delete_allでは、peoples_category1〜3もpeopleと共に削除することになります。
これは上述の2の方法です。
:nullifyは、people_idにnilを入れてpeoples_category1〜3を保存します。データは消えません。
エラーも発生しません。これは上述の3の方法です。
それ以降のオプションは1の方法と対応します。
1〜3で適切な方法を検討いただいて、dependentオプションを設定してみてください。