0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

親子関係のデータの削除を失敗しました

Last updated at Posted at 2019-01-10

controllerでのdestroy対象に漏れがあった

投稿を削除した後にログインしている人のユーザーホームに移動しようとしたらエラーになった

NoMethodError in Users#show
undefined method `story' for 2:Integer
ActionView::Template::Error (undefined method `story' for nil:NilClass):

コンソールで見るとlikeは取れているが
like.impressionはnil
ライクはあるのにそれにひもづいた感想がない
なんで感想がないのか思い至らなかったが感想を消した時に原因がありそうに思った(レッスン中)

HTML

_likes.html.rb
  <% likes.each do |like| %>
    <div class="user_story">
      <%= like.user.nicename %>
      <%= like.impression.impressions %> # 今回のエラー箇所
    </div>
  <% end %>

ユーザー詳細ページにrenderされている
投稿を削除したときのdestoryの指定が甘かったのでいくつか生き残った欠片がエラーの原因
ユーザー詳細画面には自分の投稿を見ることのできる_user.html.erbと、
自分がお気に入りした投稿を見ることのできる_like.html.erbをつくってあるが
お気に入りの方_like.html.erbでエラーが出た

コントローラー修正前

books_controller.rb
    def destroy
      @book = Book.find(params[:id])
      @impression = Impression.find(params[:id])
      @impression.destroy
      @book.destroy
      redirect_to "/index"
    end

上のコードだと
・感想に紐づいたLikeが削除されない
・コメントも削除されない
・二つともparams[:id]を使って探しているがもしidが違った場合エラーの原因になる

なので

・取得するデータの起点を一つにして連鎖的に投稿に紐づくデータを削除させる
・Likeを取得してdestroyさせたい

コントローラー修正後

books_controller.rb
    def destroy
      # params[:id] と impression.id は同じになっている
      @book = Book.find(params[:id])
      @impressions = @book.impressions
      @impressions.each do |impression|
        @likes = impression.likes
        @likes.each do |like|
          like.destroy
        end
        impression.destroy
      end
      @book.destroy
      redirect_to "/index"
    end

本のデータを探して、見つかった感想たちを回してライクを取得してdestroyする
コメントも取得して消しておく。作業はlikeと同じ。エラーでなかったから忘れていた作業です

:dependent => :destroyは失敗

:dependent => :destroyだけだと同じエラーになったので、更に子モデルに:dependent => :nullifyを指定したけれどlike,commentまで消えてくれなかった

book.rb
   has_many :impressions, :dependent => :destroy
impression.rb
    has_many :comments, :dependent => :nullify
    has_many :likes, :dependent => :nullify
books_controller.rb
      @book = Book.find(params[:id])
      @book.destroy
      redirect_to "/index"

問題はコントローラーにありそうだけれどもなんでしょうね。

追記

頂いたコメント通りに試しに子モデルに当てていた

:dependent => :nullify

:dependent => :destroy

に変えてみたところ、要素の削除に成功しました。
ありがとうございます

impression.rb
    has_many :comments, :dependent => :destroy
    has_many :likes, :dependent => :destroy

外部キーとは他のテーブルのidを指し示すものだとのこと

読んでくれてありがとう

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?