質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

13911閲覧

railsでデータを削除できません。

y.akihiro

総合スコア12

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

3クリップ

投稿2015/11/14 11:06

編集2015/11/23 12:23
PG::ForeignKeyViolation: ERROR: update or delete on table "people" violates foreign key constraint "fk_rails_c7c0232d36" on table "categories_people" DETAIL: Key (id)=(2) is still referenced from table "categories_people". : DELETE FROM "people" WHERE "people"."id" = $1

上記のようなエラーが出ました。

personとperiodとcategoryの3つのテーブルがあります。
そして、personと同時にperiodとcategoryを登録できるようになっています。
personとperiod、personとcategoryが紐付けされている2つの中間テーブルが存在しています。

中間テーブルにデータを送って登録や変更をすることはできているんですが、データを削除することができません。削除しようとするとエラーが出ます。

多分modelの設定が間違ってると思うんですが、どうすればいいかわかりません。
中間テーブルは、belongs_toを使っています。
それ以外は、has_manyやthroughを使っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rifuch

2015/11/16 01:28

影響を与えているのは明らかにモデル定義ですが、なぜこうなったのかは、モデル定義を見なければ答えられません。モデル定義を示してください。
rifuch

2015/11/24 04:08

モデル定義の言葉が曖昧でしたね。モデルクラスの関連の設定をしている部分、マイグレーション、あと、エラーが発生する(多分コントローラの)呼び出し部分のソースを見せて頂けませんか?
guest

回答1

0

こちらは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. エラーとして知らせる(今回のケース)
  2. 不要なデータをデータベース管理機能が判断して自動的に消す
  3. 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オプションを設定してみてください。

投稿2015/11/24 12:00

tink1e_

総合スコア31

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問