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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

1259閲覧

railsにてバリデーションのエラーメッセージが表示されません。undefined method `errors'

iyteratail

総合スコア1

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2021/07/24 14:15

編集2021/07/25 13:20

前提・実現したいこと

rails初心者です。
読んだ本の感想を投稿する簡易的なアプリケーションを作成しています。
現在、フォームが空欄だった時のエラーメッセージを表示する部分を実装しています。

バリデーションのエラーメッセージを表示するためには現在のコードをどのように変更すればいいのか、ご教示いただけますでしょうか。。
下記がエラーメッセージと現在のコードとなります。

発生している問題・エラーメッセージ

当初
indexのページに飛ぼうとすると、下記エラーメッセージが表示されます。

errormessage

1NoMethodError in Books#index 2Showing /home/ec2-user/environment/bookers/app/views/books/index.html.erb where line #29 raised: 3 4undefined method `errors' for #<Book::ActiveRecord_Relation:0x00007f15b00ba0a0>

該当のソースコード

Controller

1class BooksController < ApplicationController 2 def index 3 @books = Book.all 4 end 5 6 def new 7 @book = Book.new 8 end 9 10 def create 11 book = Book.new(book_params) 12 if book.save 13 flash[:notice] = "Book was successfully created." 14 redirect_to book_path(book.id) 15 else 16 #下記がelseの後に行き着く画面 17 @books = Book.all 18 render :index 19 end 20 end 21 22 def show 23 @book = Book.find(params[:id]) 24 end 25 26 def edit 27 @book = Book.find(params[:id]) 28 end 29 30 def update 31 book = Book.find(params[:id]) 32 book.update!(book_params) 33 p "標準出力にのみ反映" 34 logger.debug("標準出力とログファイルに記録される") 35 redirect_to book_path(book) 36 end 37 38 def destroy 39 book = Book.find(params[:id]) 40 book.destroy 41 redirect_to books_path 42 end 43 44 45 private 46 def book_params 47 params.permit(:title, :body) 48 end 49 50end 51

indexERB

1<header></header> 2 3<main class="top"> 4 <h1>Books</h1> 5 6 <!--テーブル入力欄はここから--> 7 <table> 8 <tr> 9 <th>Title</th> 10 <th>Body</th> 11 </tr> 12 <% @books.each do |book| %> 13 <tr> 14 <td><%= book.title %></td> 15 <td><%= book.body %></td> 16 <!--なぜここのリンクはbook.idになるのか?--> 17 <!--本来なら(@book)で行けるのでは?--> 18 <td><%= link_to "Show", book_path(book.id)%></td> 19 <td><%= link_to "Edit", edit_book_path(book.id) %></td> 20 <td><%= link_to "Destroy", book_path(book), method: :delete, "data-confirm" => "Are you sure?" %></td> 21 </tr> 22 <% end %> 23 </table> 24 <!--テーブル入力欄はここまで--> 25 26 <h2>New book</h2> 27 28 <!--- ここからエラーメッセージの出力 --> 29 <% if @books.errors.any? %> 30 <%= @books.errors.count %>prohibited this book from being saved: 31 <ul> 32 <% @books.errors.full_messages.each do |message| %> 33 <li> 34 <%= message %> 35 </li> 36 <% end %> 37 </ul> 38 <% end %> 39 40 41 <!--フォーム×2 + 投稿ボタンはここから--> 42 <%= form_with model:@book, local: true do |f| %> 43 <h5>Title</h5> 44 <%= f.text_field :title %> 45 <h5>Body</h5> 46 <%= f.text_area :body %> 47 48 <%= f.submit 'Create Book' %> 49 <% end %> 50 <!--フォーム×2 + 投稿ボタンはここまで--> 51</main> 52 53<footer></footer>

ここから以下は追記です(2021/7/25/13:11)

現在
winterboum様にご回答いただき、いただいたアドバイスを元に変更してみたところ、バリデーションのエラーメッセージが表示されるようになりました!

一方で、ボタンをクリックすると常にエラーメッセージが表示されるようになってしまい、新規投稿が保存されなくなるという処理になってしまいました。。

2 errors prohibited this book from being saved: ・Title can't be blank ・Body can't be blank

現在、エラーは出ていないのですが、上記の状態となっております。

以下がコードになります!

Controller

1class BooksController < ApplicationController 2 def index 3 @books = Book.all 4 @book = Book.new 5 6 end 7 8 def new 9 @book = Book.new 10 end 11 12 def create 13 @book = Book.new(book_params) 14 if @book.save 15 flash[:notice] = "Book was successfully created." 16 redirect_to book_path(@book.id) 17 else 18 #下記がelseの後に行き着く画面 19 @books = Book.all 20 render :index 21 end 22 end 23 24 def show 25 @book = Book.find(params[:id]) 26 end 27 28 def edit 29 @book = Book.find(params[:id]) 30 end 31 32 def update 33 book = Book.find(params[:id]) 34 book.update!(book_params) 35 p "標準出力にのみ反映" 36 logger.debug("標準出力とログファイルに記録される") 37 redirect_to book_path(book) 38 end 39 40 def destroy 41 book = Book.find(params[:id]) 42 book.destroy 43 redirect_to books_path 44 end 45 46 47 private 48 def book_params 49 params.permit(:title, :body) 50 end 51 52end 53

indexERB

1<header></header> 2 3<main class="top"> 4 <h1>Books</h1> 5 6 <!--テーブル入力欄はここから--> 7 <table> 8 <tr> 9 <th>Title</th> 10 <th>Body</th> 11 </tr> 12 <% @books.each do |book| %> 13 <tr> 14 <td><%= book.title %></td> 15 <td><%= book.body %></td> 16 <!--なぜここのリンクはbook.idになるのか?--> 17 <!--本来なら(@book)で行けるのでは?--> 18 <td><%= link_to "Show", book_path(book.id)%></td> 19 <td><%= link_to "Edit", edit_book_path(book.id) %></td> 20 <td><%= link_to "Destroy", book_path(book), method: :delete, "data-confirm" => "Are you sure?" %></td> 21 </tr> 22 <% end %> 23 </table> 24 <!--テーブル入力欄はここまで--> 25 26 <h2>New book</h2> 27 28 <!--- ここからエラーメッセージの出力 --> 29 <% if @book.errors.any? %> 30 <%= @book.errors.count %> errors prohibited this book from being saved: 31 <ul> 32 <% @book.errors.full_messages.each do |message| %> 33 <li> 34 <%= message %> 35 </li> 36 <% end %> 37 </ul> 38 <% end %> 39 40 41 <!--フォーム×2 + 投稿ボタンはここから--> 42 <%= form_with model:@book, local: true do |f| %> 43 <h5>Title</h5> 44 <%= f.text_field :title %> 45 <h5>Body</h5> 46 <%= f.text_area :body %> 47 <div> 48 <%= f.submit 'Create Book' %> 49 </div> 50 51 <% end %> 52 <!--フォーム×2 + 投稿ボタンはここまで--> 53</main> 54 55<footer></footer>

bookModel

1class Book < ApplicationRecord 2 validates :title, presence: true 3 validates :body, presence: true 4end 5

どうかよろしくお願いいたします。。

試したこと

https://teratail.com/questions/299480?link=qa_related_pc_sidebar
上記を参考にcreateアクション内の定義を確認

変数名のミスが無いかを確認

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

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

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

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

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

guest

回答1

0

ベストアンサー

@books は Bookではなくその集合体ですから errorsはありません
書くなら @book ですが、def indexでは @book定義していないから、そのエラーに変わりますが。

そのエラー:Nil には errorsはない

投稿2021/07/24 23:40

編集2021/07/24 23:41
winterboum

総合スコア23284

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

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

iyteratail

2021/07/26 13:12 編集

winterboum様 ご回答いただき、ありがとうございます。 いただいたアドバイスを元に変更してみたところ、バリデーションのエラーメッセージが表示されるようになりました。 一方で、ボタンをクリックすると常にエラーメッセージが表示されるようになってしまい、新規投稿が保存されなくなるという処理になってしまいました。 私自身、どこを変更したらいいのか、分からず1時間ほど苦しんでおります。 恐れ入りますが、コードをご確認いただくことは可能でしょうか。 お忙しい中大変申し訳ありませんが、何卒よろしくお願いいたします。
winterboum

2021/07/25 03:42

1 読みにくいので、質問欄を編集して、<code>で書いてください。 2 エラーメッセージは全文載せてください
winterboum

2021/07/25 03:43

あと、おそらく model Bookのcodeも必要になりますから、それも載せて
iyteratail

2021/07/25 04:13

winterboum様 お世話になっております。 こちら質問欄を編集いたしました。 現在はエラーが出ていないため、エラーメッセージは記載していない状態でございます。 お忙しいところ申し訳ございません。 何卒よろしくお願いいたします。
winterboum

2021/07/25 04:15

エラーが出ない。そうすると何が問題なの?
iyteratail

2021/07/25 09:05 編集

ありがとうございます。 ボタンをクリックすると常にエラーメッセージが表示されるようになってしまい、新規投稿が保存されなくなるという問題が起きてしまっています…。 こちら言葉足らずで大変申し訳ございませんでした。
winterboum

2021/07/25 11:25

そのエラーメッセージを載せtrください
iyteratail

2021/07/25 13:18

エラーメッセージ下記になります。 railsでのエラーではなく、バリデーションによって表示させているエラーです。 ご認識に齟齬がございましたら、申し訳ございません。。 --- 2 errors prohibited this book from being saved: ・Title can't be blank ・Body can't be blank ---
winterboum

2021/07/25 22:48

def book_params を params.require(:book).permit(:title, :body) に
iyteratail

2021/07/26 12:20

返信遅くなってしまい、申し訳ございません。 今コードの編集を行ったところ、全てが正常に動くようになりました!! 本当にありがとうございます! 差し支えなければ教えていただけると幸いなのですが、、 winterboum様はどのようにして上記コードの部分にて修正が必要と分かったのでしょうか? 今後自身でエラーを解決する時に参考にさせていただけますと幸いです。
winterboum

2021/07/26 12:47

・Title can't be blank から titleへの入力が nil になっている、と判断 params.permit(:title, :body) に違和感 <%= form_with model:@book, でやっぱり
iyteratail

2021/07/26 13:11

ありがとうございます! そのように辿ることができるんですね…。 私もいつかwinterboum様のように自力でエラーを解決できるよう、頑張っていきます! ありがとうございました!!
iyteratail

2021/07/26 14:44

エラーが発生した時にlogを見る癖がまだついていませんでした。 (具体的にどこを見ればいいのかすら分からず、理解不能だったという方が正しいかもしれません…) logからも目を背けず日々学習していきたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問