前提・実現したいこと
rails初心者です.現在,友達間で授業の情報を書き留めておけるページを作っています.
このサイトは,room(授業名を書く)とreview(授業の情報を書く)がネストになっています.(roomが親で,reviewが子です)
相談としては,
(1)
授業情報(review)をeditの画面(edit.html.erb)で編集し,更新(update)する時に,
No route matches [PATCH] "/rooms/8/reviews"
というエラーが出て更新がうまくできていません.
なぜこのようなエラーが出るのか,そしてこの問題をどのようにして解決するのか(或いはそこに至る考え方)を知りたいです.
なお,授業情報(review)の作成(new, createアクション)や表示(indexやshow)は問題なくできています.
ネット等でもネストや自分と同じエラーが出た方の記事を参考にしましたが,解決には至りませんでした.
気になったこと
(2)不思議に思うのが,rails routesでルーチングを見てみると,更新アクションにあたるupdateに該当するreviews#updateのリンクが, /rooms/:room_id/reviews/:id(.:format)となっています.しかし,エラー画面で出ているのは/rooms/:room_id/reviewsと,後ろの:idがないものとなっています.
なぜこのような/rooms/:room_id/reviewsというrails routesにはないurlが生成されてしまったのでしょうか?
(3)送信後のデータについて,
Parameters: {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"aXt74o039/vovChxbQHPnGl/VFej2t9+SRH+Mr9mJE00LTDsgYBqWYxB3Qz2xTKDLDa0nPj3l5GAeRAVN80hg==", "review"=>{"name"=>"まりおさん", "year"=>"2020", "note"=>"数学の小テストは明日行われます"}, "commit"=>"記入完了"}
となっており,なぜreviewのidがパラメータの中に送られていないのも大変気になります.form_with~の書き方に問題があるのでしょうか?
エラーメッセージ
No route matches [PATCH] "/rooms/8/reviews"
該当のソースコード
長くなります.ご了承ください.
reviews_controller.html.erb
※find_by~という同じコードが多数ありますが,あとでまとめようと考えています.なのでいまはごちゃごちゃしていますが,ご了承ください.
reviews_controller.html.erb
1class ReviewsController < ApplicationController 2 def new 3 @room = Room.find(params[:room_id]) 4 @review = Review.new 5 end 6 7 def create 8 @room = Room.find(params[:room_id]) 9 @review = @room.reviews.build(review_params) 10 11 if @review.save 12 flash[:success] = "授業情報を更新しました" 13 redirect_to room_reviews_path 14 else 15 flash[:danger] = "授業情報の登録に失敗しました" 16 render :new 17 end 18 end 19 20 def show 21 @room = Room.find_by(id: params[:room_id]) 22 @review = @room.reviews.find(params[:id]) 23 end 24 25 def index 26 @room = Room.find_by(id: params[:room_id]) 27 @reviews = @room.reviews.order(id: :desc).page(params[:page]).per(40) 28 end 29 30 def edit 31 @room = Room.find_by(id: params[:room_id]) 32 @review = @room.reviews.find(params[:id]) 33 end 34 35 36 def update 37 38 @room = Room.find_by(id: params[:room_id]) 39 #@review = @room.reviews.where(review_params) 40 @review = @room.reviews.find(params[:id]) 41 42 if @review.update(review_params) 43 flash[:success] = "正常に登録されました" 44 redirect_to room_reviews_path 45 else 46 flash[:danger] = "再度登録作業をしてください" 47 render :edit 48 end 49 end 50 51 52 def destroy 53 @room = Room.find_by(id: params[:room_id]) 54 @review = @room.reviews.find_by(id: params[:id]) 55 56 @review.destroy 57 flash[:success] = "削除しました" 58 redirect_to room_reviews_path 59 end 60 61 private 62 63 def review_params 64 params.require(:review).permit(:name, :note, :year) 65 end 66 67 68end 69 70
edit.html.erb
※new.html.erbも,記入完了の上に記入上の注意に関する文章を書いている以外は,同じコードとなっています.
edit.html.erb
1 2<h1><%= @room.class_name %>の授業情報の編集</h1> 3 4<div> 5 <%= form_with(model: [@room, @review], url: room_reviews_path, local: true) do |f| %> 6 7 <div class ="form-group"> 8 <%= f.label :name, "あなたのあだ名" %> 9 <%= f.text_field :name, class: "form-control" %> 10 </div> 11 12 <div class ="form-group"> 13 <%= f.label :year, "あなたの入学年(数字4桁で書いてください)" %> 14 <%= f.number_field :year, class: "form-control" %> 15 </div> 16 17 <div class = "form_group mb-3"> 18 <%= f.label :note, "授業情報" %> 19 <%= f.text_area :note, class: "form-control", rows: 5 %> 20 </div> 21 22 <%= f.submit "記入完了", class: "btn btn-block btn-primary" %> 23 24 <% end %> 25 26</div> 27
route.rb (ルーチング)
route.rb
1 2Rails.application.routes.draw do 3 4 #patch "/rooms/:room_id/reviews", to: "reviews#update" 5 6 root to:"rooms#index" 7 8 resources :rooms do 9 resources :reviews 10 end 11
review.rb
Review.rb
1 2class Review < ApplicationRecord 3 belongs_to :room 4 5 validates :name, presence: true, length: { maximum: 20 } 6 validates :note, presence: true 7 validates :year, presence: true, numericality: true, length: { maximum: 4 } 8end
room.rb
room.rb class Room < ApplicationRecord validates :class_name, presence: true, length: { maximum: 50 } has_many :reviews end
ルーチングのスクリーンショット(気になったことに貼ったものと同じです)
ルーチングのスクリーンショット
エラー画面のスクリーンショット(気になったことに貼ったものと同じです)
エラー画面のスクリーンショット
試したこと
コードのところどころにある#のあとのコードが試した名残りです.
No route matches [PATCH] "/rooms/8/reviews"のエラーが表示されたので,route.rbにpatch "/rooms/:room_id/reviews", to: "reviews#updateというコードを書き足した.そうすると,エラーが表示された.idが見つからないので,
@review = @room.reviews.where(review_params)を@review = @room.reviews.find(params[:id])の代わりに書いてみると,no route matchesのエラーは出なくなったが.まったく自分が加えた変更が更新もされずに,indexのページに遷移した.
他にもform_withについて,urlを書き足したり,modelに書いてあるインデックス変数の順番を変えたりもしましたが,大きく変化はありません.
補足情報(FW/ツールのバージョンなど)
質問を(1)~(3)の部分に番号のあとに書いて整理してあります.
はじめての質問で至らない部分があるかと思いますがよろしくお願いします.
開発環境
ruby 2.5.3
Rails 5.2.4.2
AWS cloud9
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/02 15:29
2020/06/02 15:35
2020/06/05 15:17
2020/06/05 23:13
2020/06/06 08:23