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

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

ただいまの
回答率

87.61%

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 101

score 1

前提・実現したいこと

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

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

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

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

NoMethodError in Books#index
Showing /home/ec2-user/environment/bookers/app/views/books/index.html.erb where line #29 raised:

undefined method `errors' for #<Book::ActiveRecord_Relation:0x00007f15b00ba0a0>

該当のソースコード

class BooksController < ApplicationController
  def index
    @books = Book.all
  end

  def new
    @book = Book.new
  end

  def create
    book = Book.new(book_params)
    if book.save
      flash[:notice] = "Book was successfully created."
      redirect_to book_path(book.id)
    else
      #下記がelseの後に行き着く画面
      @books = Book.all
      render :index
    end
  end

  def show
    @book = Book.find(params[:id])
  end

  def edit
    @book = Book.find(params[:id])
  end

  def update
    book = Book.find(params[:id])
    book.update!(book_params)
    p "標準出力にのみ反映"
    logger.debug("標準出力とログファイルに記録される")
    redirect_to book_path(book)
  end

  def destroy
    book = Book.find(params[:id])
    book.destroy
    redirect_to books_path
  end


  private
  def book_params
    params.permit(:title, :body)
  end

end
<header></header>

<main class="top">
  <h1>Books</h1>

  <!--テーブル入力欄はここから-->
  <table>
    <tr>
      <th>Title</th>              
      <th>Body</th>                      
    </tr>
   <% @books.each do |book| %>
    <tr>
      <td><%= book.title %></td>
      <td><%= book.body %></td>
      <!--なぜここのリンクはbook.idになるのか?-->
      <!--本来なら(@book)で行けるのでは?-->
      <td><%= link_to "Show", book_path(book.id)%></td>    
      <td><%= link_to "Edit", edit_book_path(book.id) %></td>
      <td><%= link_to "Destroy", book_path(book), method: :delete, "data-confirm" => "Are you sure?" %></td>
    </tr>
    <% end %>
   </table>
  <!--テーブル入力欄はここまで-->

  <h2>New book</h2>

  <!--- ここからエラーメッセージの出力 -->
  <% if @books.errors.any? %>
    <%= @books.errors.count %>prohibited this book from being saved:
    <ul>
      <% @books.errors.full_messages.each do |message| %>
      <li>
        <%= message %>
      </li>
      <% end %>
    </ul>
  <% end %>


  <!--フォーム×2 + 投稿ボタンはここから-->
  <%= form_with model:@book, local: true do |f| %>
    <h5>Title</h5>
    <%= f.text_field :title %>
    <h5>Body</h5>
    <%= f.text_area :body %>

    <%= f.submit 'Create Book' %>
  <% end %>
  <!--フォーム×2 + 投稿ボタンはここまで-->
</main>

<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

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

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

class BooksController < ApplicationController
  def index
    @books = Book.all
    @book = Book.new

  end

  def new
    @book = Book.new
  end

  def create
    @book = Book.new(book_params)
    if @book.save
      flash[:notice] = "Book was successfully created."
      redirect_to book_path(@book.id)
    else
      #下記がelseの後に行き着く画面
      @books = Book.all
      render :index
    end
  end

  def show
    @book = Book.find(params[:id])
  end

  def edit
    @book = Book.find(params[:id])
  end

  def update
    book = Book.find(params[:id])
    book.update!(book_params)
    p "標準出力にのみ反映"
    logger.debug("標準出力とログファイルに記録される")
    redirect_to book_path(book)
  end

  def destroy
    book = Book.find(params[:id])
    book.destroy
    redirect_to books_path
  end


  private
  def book_params
    params.permit(:title, :body)
  end

end
<header></header>

<main class="top">
  <h1>Books</h1>

  <!--テーブル入力欄はここから-->
  <table>
    <tr>
      <th>Title</th>              
      <th>Body</th>                      
    </tr>
   <% @books.each do |book| %>
    <tr>
      <td><%= book.title %></td>
      <td><%= book.body %></td>
      <!--なぜここのリンクはbook.idになるのか?-->
      <!--本来なら(@book)で行けるのでは?-->
      <td><%= link_to "Show", book_path(book.id)%></td>    
      <td><%= link_to "Edit", edit_book_path(book.id) %></td>
      <td><%= link_to "Destroy", book_path(book), method: :delete, "data-confirm" => "Are you sure?" %></td>
    </tr>
    <% end %>
   </table>
  <!--テーブル入力欄はここまで-->

  <h2>New book</h2>

  <!--- ここからエラーメッセージの出力 -->
  <% if @book.errors.any? %>
    <%= @book.errors.count %> errors prohibited this book from being saved:
    <ul>
      <% @book.errors.full_messages.each do |message| %>
      <li>
        <%= message %>
      </li>
      <% end %>
    </ul>
  <% end %>


  <!--フォーム×2 + 投稿ボタンはここから-->
  <%= form_with model:@book, local: true do |f| %>
    <h5>Title</h5>
    <%= f.text_field :title %>
    <h5>Body</h5>
    <%= f.text_area :body %>
    <div>
      <%= f.submit 'Create Book' %>
    </div>

  <% end %>
  <!--フォーム×2 + 投稿ボタンはここまで-->
</main>

<footer></footer>
class Book < ApplicationRecord
  validates :title, presence: true
  validates :body, presence: true
end

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

試したこと

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/07/26 22:11

    ありがとうございます!
    そのように辿ることができるんですね…。

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

    キャンセル

  • 2021/07/26 22:34

    log も役立ちます

    キャンセル

  • 2021/07/26 23:44

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

    logからも目を背けず日々学習していきたいと思います!

    キャンセル

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

  • ただいまの回答率 87.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る