回答編集履歴

1

追記

2023/01/19 00:32

投稿

shinoharat
shinoharat

スコア1674

test CHANGED
@@ -35,3 +35,54 @@
35
35
  end
36
36
  ```
37
37
 
38
+ --
39
+
40
+ ## 追記:
41
+ ### エラー原因の解説
42
+
43
+ 以下のエラーは「外部キー制約」に失敗しているために表示されます。
44
+
45
+ > ActiveRecord::InvalidForeignKey in DesignsController#destroy
46
+ > Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails
47
+
48
+ 例えば、「デザインA」に「Tag: Ruby」と「Tag: Java」の2つが紐づいている場合、DBでは以下のようなデータ構造になります。
49
+
50
+ **[designs]**
51
+ | id | title |
52
+ | 11 | デザインA |
53
+
54
+ **[post_tag_relations]**
55
+ | id | design_id | tag_id |
56
+ | 1 |    11 |   21 |
57
+ | 2 |    11 |   22 |
58
+
59
+ **[tags]**
60
+ | id | tag_name |
61
+ | 21 | Ruby |
62
+ | 22 | Java |
63
+
64
+ ここで単純に「デザインAだけ」を消すと、 post_tag_relations テーブルに「存在しない design_id 」が発生してしまいます。
65
+
66
+ **[post_tag_relations]**
67
+ | id | design_id | tag_id |
68
+ | 1 |   :warning:11 |   21 | ← 「存在しない ID を指し示すのはおかしくね?」とMySQL君が気をきかせる
69
+ | 2 |   :warning:11 |   22 |
70
+
71
+ なので、そうならないようにエラーを発生させて、データの整合性を保とうとするわけです。
72
+ それが、エラーメッセージ「Cannot delete or update a parent row: a foreign key constraint fails」の意味です。
73
+
74
+ ### 修正方法
75
+
76
+ 単純に designs だけを消すのではなく、関連する post_tag_relations も一緒に消す必要があります。
77
+ コードの修正はすごく簡単で、モデル側に `dependent: :destroy` のオプションを付けるだけです。
78
+
79
+ ```diff
80
+ class Design < ApplicationRecord
81
+ belongs_to :user
82
+ - has_many :post_tag_relations
83
+ + has_many :post_tag_relations, dependent: :destroy
84
+ has_many :tags, through: :post_tag_relations
85
+ has_one_attached :image
86
+
87
+ ・・・略・・・
88
+ ```