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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

1787閲覧

[Rails] destroyしたいレコードと別のレコードが削除される。

kokotaro

総合スコア22

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2019/07/10 04:12

編集2019/07/10 05:39

Todoアプリを作っています。
Categoryモデル(親)とTodoモデル(子)の関係です。
categoryを投稿して、各Categoryのshowアクションのビューでtodoを投稿することができます。
todoはeachで表示させ各todoに削除ボタンをつけてます。

#####起きてる問題
今回、todoの削除機能を実装しているのですが、削除ボタンを押すと削除したいレコードでなく一番古いレコードから削除されてしまいます。
コントローラー側のdestroyアクションにての削除するレコードの指定の仕方が合ってないと思うのですが、わかりません。

ルーティング Rails.application.routes.draw do root 'categories#index' resources :categories, only: [:index, :show, :create, :edit,:update, :destroy] do resources :todos, only: [:create,:edit,:update,:destroy] end end
categoriesコントローラー class CategoriesController < ApplicationController before_action :set_category,only:[:show,:destroy,:edit,:update] def index @categories = Category.all @category = Category.new end def show @todos = @category.todos @todo = Todo.new end def create @category = Category.create(category_params) if @category.save redirect_to root_path else render :index end end def edit end def update @category.update(category_params) if @category.save redirect_to root_path else render :index end end def destroy @category.destroy redirect_to root_path end private def category_params params.require(:category).permit( :name) end def set_category @category = Category.find(params[:id]) end end
todoコントローラー class TodosController < ApplicationController before_action :set_category,only:[:create] def create @todo = Todo.create(todo_params) if @todo.save redirect_to category_path(@category.id) else redirect_to category_path(@category.id) end end def destroy @todo= Todo.find_by(params[:id]) #これだと一番古いレコードから削除されてしまう。 @todo.destroy redirect_to category_path end private def todo_params params.require(:todo).permit( :description,:date).merge(category_id: @category.id) end def set_category @category = Category.find_by(id:params[:category_id]) end end
ビュー cetagories/show.html.haml = form_for [@category,@todo] , html: { class: "category" } do |f| %p Todo = f.text_area :description, placeholder: "Todoタスクを入力してください(150字以内)", type: "text", class: 'category__name' = f.date_field :date, type:"date" = f.submit '作成する', class: 'category__submit' - if @todos.present? - @todos.each do |todo| .category-box .category-box__name = todo.description = todo.date .category-box__edit = link_to '削除', category_todo_path(@category.id,todo.id), method: :delete

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

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

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

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

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

guest

回答1

0

ベストアンサー

@todo= Todo.find_by(params[:id]) #これだと一番古いレコードから削除されてしまう。

find_byの使い方を間違えているように思います。

ruby

1@todo = Todo.find_by(id: params[:id])

では、どうでしょうか?

投稿2019/07/10 04:36

asm

総合スコア15147

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

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

asm

2019/07/10 04:41

Todo.find(params[:id])でもよい気がしますね。 存在しないidを指定した場合に勝手に404にしてくれるので楽です。
kokotaro

2019/07/10 04:43

そちらも試してみたのですがnilになってエラーになってしまいます。 [2] pry(#<CategoriesController>)> Todo.find_by(id:params[:id]) Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 6], ["LIMIT", 1]] ↳ (pry):16 => nil
asm

2019/07/10 04:54

見落としがあったようですね。失礼しました。 > = link_to '削除', category_todo_path(todo.id), method: :delete ここにもミスがあります。 resourcesがネストしているので、category_todo_path(@category.id, todo.id)になります。
kokotaro

2019/07/10 05:44

そちらも試したみたのですがエラーになってしまいます。 以下logになります。 Started DELETE "/categories/7/todos/64" for ::1 at 2019-07-10 14:39:58 +0900 Processing by TodosController#destroy as HTML Parameters: {"authenticity_token"=>"jUmZa3fqSlEzoX0nc4fA881RwF7+aINbb2sEiTiyoJD2mbM2uMCs2dHL83y4P9RJxHJsvyJLNH//8ZPlOsHUnQ==", "category_id"=>"7", "id"=>"64"} Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT ? [["id", 7], ["LIMIT", 1]] ↳ app/controllers/todos_controller.rb:42 Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 64], ["LIMIT", 1]] ↳ app/controllers/todos_controller.rb:30 (0.1ms) begin transaction ↳ app/controllers/todos_controller.rb:31 Todo Destroy (0.4ms) DELETE FROM "todos" WHERE "todos"."id" = ? [["id", 64]] ↳ app/controllers/todos_controller.rb:31 (1.8ms) commit transaction ↳ app/controllers/todos_controller.rb:31 Redirected to http://localhost:3000/categories/64 Completed 302 Found in 6ms (ActiveRecord: 2.7ms) Started GET "/categories/64" for ::1 at 2019-07-10 14:39:58 +0900 Processing by CategoriesController#show as HTML Parameters: {"id"=>"64"} Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT ? [["id", 64], ["LIMIT", 1]] ↳ app/controllers/categories_controller.rb:47 Completed 404 Not Found in 1ms (ActiveRecord: 0.1ms) ActiveRecord::RecordNotFound (Couldn't find Category with 'id'=64): app/controllers/categories_controller.rb:47:in `set_category'
asm

2019/07/10 07:05

見た感じ削除自体は成功していそうです 最後のredirect_toを redirect_to category_path(@category.id) に変えるとどうでしょうか?
kokotaro

2019/07/10 07:20

ありがとうございました!! redirect_toの変更で削除がうまくいくようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問