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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

Q&A

解決済

1回答

710閲覧

助けて欲しいです!中間テーブル作成後user削除ができなくなってしまいました

ko.nakamura

総合スコア3

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

0グッド

0クリップ

投稿2021/04/03 12:51

編集2021/04/04 00:43

##前提・実現したいこと
中間テーブルを用いた商品の確認機能を実装後、user削除ができなくなりました。
これを解決したいです!
ちなみにuserを削除してもそのユーザーが投稿した商品は削除しないです。
##発生している問題・エラーメッセージ

ActiveRecord::InvalidForeignKey in UsersController#destroy Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails (`kyo_yu_2021_development`.`items`, CONSTRAINT `fk_rails_d4b6334db2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) Extracted source (around line #9): def destroy @user = User.find(params[:id]) ????ここが赤いです if @user.destroy redirect_to root_path end end

##該当のソースコード

ruby

1app/models/user.rb 2 3class User < ApplicationRecord 4 # Include default devise modules. Others available are: 5 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 6 devise :database_authenticatable, :registerable, 7 :recoverable, :rememberable, :validatable 8 9 validates :user_name, presence: true 10 11 has_many :items, dependent: :destroy 12 has_many :web_confirmations, dependent: :destroy 13 has_many :items, through: :web_confirmations, dependent: :destroy 14 has_many :local_confirmations, dependent: :destroy 15 has_many :items, through: :local_confirmations, dependent: :destroy 16end

ruby

1app/models/item.rb 2 3class Item < ApplicationRecord 4 5 belongs_to :user 6 has_one_attached :image, dependent: :destroy 7 has_many :web_confirmations, dependent: :destroy 8 has_many :users, through: :web_confirmations, dependent: :destroy 9 has_many :local_confirmations, dependent: :destroy 10 has_many :users, through: :local_confirmations, dependent: :destroy 11 extend ActiveHash::Associations::ActiveRecordExtensions 12 belongs_to :stock 13 14 with_options presence: true do 15 validates :image 16 validates :name, length: { maximum: 50 } 17 validates :text, length: { maximum: 1000 } 18 validates :deployment 19 validates :arrival_day 20 end 21 validates :stock_id, numericality: { other_than: 1 } 22 23 def self.search(search) 24 if search != "" 25 Item.where('name LIKE(?) or text LIKE(?) or arrival_day LIKE(?)', "%#{search}%", "%#{search}%", "%#{search}%") 26 else 27 Item.all.order("created_at DESC").limit(10) 28 end 29 end 30end

ruby

1app/models/web_confirmation.rb 2 3class WebConfirmation < ApplicationRecord 4 5 belongs_to :user 6 belongs_to :item 7 8 validates_uniqueness_of :item_id, scope: :user_id 9end

ruby

1app/models/local_confirmation.rb 2 3class LocalConfirmation < ApplicationRecord 4 5 belongs_to :user 6 belongs_to :item 7 8 validates_uniqueness_of :item_id, scope: :user_id 9 10end

web_confirmation.rbとlocal_confirmation.rbはuserとitemの中間テーブルです
##試したこと
初めはitem(商品)も削除出来なくなっていましたが、外部キーを持つデータのdestroyを行うための設定を調べた結果、dependent: :destroyを付与することで解決しました。
同様にuserもそうしてみましたが解決できません。
ぜひご意見お願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

class Item < ApplicationRecord belongs_to :user
になっているので、UserとつながったItemが有る場合はUserは削除できません。

class User < ApplicationRecord has_many :items, dependent: :destroy
とあるので行けそうなのですが、これでだめであった場合の質問がここにも有ったような覚えが。。

ただこのcaseの場合はその前に直しておくべきことがあります。
`lass User に has_many :items が3回あります。一つでないとRailsが混乱するでしょう。
見方を変えて3種のitemが関連するということはありえます。
ただしその場合は関連名を変えてください。has_many :items_by_web みたいに。
相手になるItemの方も3つのuserに対して別の関連名にする必要があります

追記
「userとitemを繋ぐ中間テーブルとしてweb_confirmationsとlocal_confirmationsが存在しています。」
であるなら、
「userとweb_confirmationsは1対多、userとlocal_confirmationsも1対多。
itemとweb_confirmationsは1対多、itemとlocal_confirmationsも1対多。」
はおかしい。共に多対多、かつ has_many :items が単独であるのもおかしい。
Item,User の 関連定義はどうなってます?

というか、、、、
1対1、1対多、多対多 の概念を勉強したほうが良いようにおもえます。

投稿2021/04/04 03:27

編集2021/04/05 02:34
winterboum

総合スコア23567

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

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

ko.nakamura

2021/04/04 13:33

丁寧な回答ありがとうございます。 私の理解力不足で申し訳ありませんが、教えていただいとように has_many :items has_many :web_confirmations, dependent: :destroy has_many :items_by_web, through: :web_confirmations, dependent: :destroy has_many :local_confirmations, dependent: :destroy has_many :items_by_local, through: :local_confirmations, dependent: :destroy と関連名を変えるということはモデル名も変えるということでしょうか?
winterboum

2021/04/04 13:44

いや、一つのモデルが3つの立場でUserと関連しているわけですから、その「一つのモデル」の名前はそのままです。関連名を変えるということです。 class_name: "Item" を入れてください。 foreign_key も必要かな
ko.nakamura

2021/04/04 14:16

丁寧にご対応していただいているのに理解力がなくて絶望しています、、 app/models/user.rb has_many :items has_many :web_confirmations, dependent: :destroy has_many :items, class_name: 'Item', foreign_key: 'item_id', through: :web_confirmations, dependent: :destroy has_many :local_confirmations, dependent: :destroy has_many :items, class_name: 'Item', foreign_key: 'item_id', through: :local_confirmations, dependent: :destroy としてみましたが違いますか?
winterboum

2021/04/04 14:42

web_confirmations のスキーマがわからないからなんとも。
ko.nakamura

2021/04/05 00:30

スキーマとはDB設計図という理解で良いでしょうか? userとitemを繋ぐ中間テーブルとしてweb_confirmationsとlocal_confirmationsが存在しています。 userとweb_confirmationsは1対多、userとlocal_confirmationsも1対多。 itemとweb_confirmationsは1対多、itemとlocal_confirmationsも1対多。 web_confirmationsとlocal_confirmationsに追加したカラムはuser_idとitem_idです。 こんなに丁寧に対応していただいているのに申し訳ございません、、、
ko.nakamura

2021/04/05 02:47

何度も丁寧にありがとうございます。 もう訳がわからなくなって頭がパンクしてしまったので、 おっしゃる通り一度勉強しなおします。
ko.nakamura

2021/04/05 04:25

解決しました。 一番初めにご指摘いただいた belongs_to :userとhas_many :itemをコメントアウトして %rails c %rails sで再起動して問題なく実装できました winterboum様、ご迷惑をおかけし申し訳ありませんでした また、理解を深めるために関連記事もこの後も読み進めます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問