🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

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

Ruby on Rails

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Q&A

解決済

1回答

4044閲覧

バリデーションを使って新規投稿時と編集時、空欄で投稿した時にエラーメッセージを表示させたい

veludo

総合スコア3

Ruby

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

Ruby on Rails

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

0グッド

0クリップ

投稿2021/03/20 01:01

編集2021/03/20 06:30

前提・実現したいこと

Rails勉強中のプログラミング初心者です。
新規投稿・閲覧・編集・削除などができる簡単なアプリケーションを作成して練習しています。
バリデーションを使って新規投稿時と編集時、空欄で投稿した時にエラーメッセージを表示させたいです。

新規投稿欄に空白で投稿すると下記のエラーが出てしまいます。
編集欄に空白で投稿するとボタンは押されるのですがエラーすら出ず、何も反応がありません。

エラーメッセージ

NoMethodError in Books#create
undefined method `each' for nil:NilClass

Request
Parameters:

{"utf8"=>"✓", "authenticity_token"=>"6UH9Tw6ev8ONJ5NbeXL3PzGOwEjQpU+ZVLm/P1AAkVogavNeOuSFSM2qkCz4neTcd1ejabAMRA/ebV5CrgMg0w==", "book"=>{"title"=>"", "body"=>""}, "commit"=>"Create Book"}

###index.html.erb

Ruby

1<% if flash[:notice] %> 2 <div class="flash"> 3 <%= flash[:notice] %> 4 </div> 5<% end %> 6 7<h1>Books</h1> 8<table> 9 <tr> 10 <th>title</th> 11 <th>body</th> 12 <th></th> 13 </tr> 14 15 <% @books.each do |book| %> 16 <tr> 17 <td><span><%= book.title %></span></td> 18 <td><span><%= book.body %></span></td> 19 <td><%= link_to "Show", show_book_path(book.id) %></td> 20 <td><%= link_to "Edit", edit_book_path(book.id) %></td> 21 <td><%= link_to "Destroy", destroy_book_path(book.id), method: :delete, "data-confirm" => "Are you sure?" %></td> 22 </tr> 23 <% end %> 24</table> 25 26 <h3>New book</h3> 27 <!-- form_with部分 --> 28 <%= form_with model: @book, url: "/books/#{@book.id}", local:true do |f| %> 29 <% if @book.errors.any? %> 30 <h3><%= @book.errors.count %>errors prohibited this book from being saved:</h3> 31 <ul> 32 <% @book.errors.full_messages.each do |message| %> 33 <li><%= message %></li> 34 <% end %> 35 </ul> 36 <% end %> 37 38 <h4>Title</h4> 39 <%= f.text_field :title %> 40 <h4>Body</h4> 41 <%= f.text_area :body %> 42 <%= f.submit 'Create Book' %> 43 <% end %>

book.rb

ruby

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

###books_controller.rb

Ruby

1class BooksController < ApplicationController 2 def index 3 @books = Book.all 4 # 投稿一覧 5 @book = Book.new 6 # 新規投稿 7 end 8 9 def create 10 @book = Book.new(book_params) 11 if @book.save 12 flash[:notice] = "Book was successfully created." 13 redirect_to show_book_path(@book) 14 else 15 #書き込み失敗 16 render :index 17 end 18 end 19 20 def show 21 @book = Book.find(params[:id]) 22 end 23 24 def new 25 end 26 27 def edit 28 @book = Book.find(params[:id]) 29 end 30 31 def update 32 book = Book.find(params[:id]) 33 if book.update(book_params) 34 flash[:notice] = "Book was successfully updated." 35 redirect_to show_book_path(book.id) 36 end 37 end 38 39 def destroy 40 book = Book.find(params[:id]) #データ(レコード)を1件取得 41 if book.destroy #データ(レコード)を削除 42 flash[:notice] = "Book was successfully destroyed." 43 redirect_to books_path(book.id) 44 end 45 end 46 47 private 48 #ストロングパラメータ 49 def book_params 50 params.require(:book).permit(:title, :body) 51 end 52end

###edit.html.erb

ruby

1<h1>Editing Book</h1> 2<!-- form_with部分 --> 3<%= form_with model: @book, url: "/books/#{@book.id}", local:true do |f| %> 4 <h4>Title</h4> 5 <%= f.text_field :title %> 6 <h4>Body</h4> 7 <%= f.text_area :body %> 8 <%= f.submit 'Update Book' %> 9 <%= link_to "Show", show_book_path(@book) %> 10 <%= link_to "Back", index_book_path(@book) %> 11<% end %>

###show.html.erb

ruby

1<% if flash[:notice] %> 2 <div class="flash"> 3 <%= flash[:notice] %> 4 </div> 5<% end %> 6 7<h2>Title:</h2> 8<p><%= @book.title %></p> 9<h2>Body:</h2> 10<p><%= @book.body %></p> 11<%= link_to "Edit", edit_book_path(@book) %> 12<%= link_to "Back", "/books" %>

new.html.erb

ruby

1<h1>New Book</h1> 2<!-- form_with部分 --> 3<%= form_with model:@book, url: '/books', local:true do |f| %> 4 <h4>Title</h4> 5 <% f.text_field :title %> 6 <h4>Body</h4> 7 <%= f.text_area :body %> 8 <%= f.submit 'Create Book'%> 9<% end %>

routes.rb

ruby

1Rails.application.routes.draw do 2 # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 3 root to: 'homes#top' 4 get 'books' => 'books#index', as: 'index_book' 5 post 'books' => 'books#create' 6 7 get 'books/:id' => 'books#show', as: 'show_book' 8 get 'books/edit' => 'books#edit' 9 get 'books/:id/edit' => 'books#edit', as: 'edit_book' 10 patch 'books/:id' => 'books#update', as: 'update_book' 11 12 delete 'books/:id' => 'books#destroy', as: 'destroy_book' 13end 14

undefined method `each' for nil:NilClassから、nil な何かには「each」メソッドがないから、実行できないと言われており、今回の場合は

ruby

1<% @books.each do |book| %>

なので、eachの前の@booksがnilということだと思うのですが、編集欄の**'Update Book'**ボタンが反応しないことも含め、ここからどう解決すればよいのか分かりません。

説明不足で申し訳ありませんが、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

newで失敗した場合 indexに飛んでます。 indexでは @books を each していますが、それが未定義なのでエラーになってます。render の前に@books = Book.all をつけましょう。
ただ、多くのアプリではsave失敗した時は new に戻って入力させ直します。
また、newに戻ったにしても載っている newのviewにはエラー表示のcedeがないので、このままではエラー表示はありません。

「編集欄に空白で投稿するとボタンは押されるのですがエラーすら出ず、何も反応がありません。」
というのが ?? です。 templateがないというエラーになると思われるのですが。
logを確認したいです

追記
「No template found for BooksController#update, rendering head :no_content
Completed 204 No Content in 25ms (ActiveRecord: 0.2ms)」
やっぱり出てますね。
else render :edit end
を追加しましょう

投稿2021/03/20 03:36

編集2021/03/20 05:58
winterboum

総合スコア23567

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

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

veludo

2021/03/20 05:07 編集

ご回答いただきありがとうございます。 説明不足で申し訳ございません。 一覧と新規投稿の画面は同じ画面に表示してあります。 Renderの前に@books = Book.allをつけたことで新規投稿欄にエラー表示されるようになりました。 編集欄に空白で投稿した際のLogはこのように表示されております。 development.log Started PATCH "/books/40" for 60.41.22.240 at 2021-03-20 03:50:52 +0000 Cannot render console from 60.41.22.240! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 Processing by BooksController#update as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"wfQIz1n/YI53SVnjVam6WlmILzUhuXHvp8zNbpwJDcB+KuTbWDFlN9b7LC/CCbB5NEMN6LV2WLkBHh3UR34NLQ==", "book"=>{"title"=>"", "body"=>""}, "commit"=>"Update Book", "id"=>"40"} Book Load (0.1ms) SELECT "books".* FROM "books" WHERE "books"."id" = ? LIMIT ? [["id", 40], ["LIMIT", 1]] ↳ app/controllers/books_controller.rb:34  (0.1ms) begin transaction ↳ app/controllers/books_controller.rb:35  (0.0ms) rollback transaction ↳ app/controllers/books_controller.rb:35 No template found for BooksController#update, rendering head :no_content Completed 204 No Content in 25ms (ActiveRecord: 0.2ms)
veludo

2021/03/20 06:35

ありがとうございます。 else      render :edit    end を追加したら、今度は undefined method `id' for nil:NilClass のエラーが出てしまいました。 抽出されたソースはedit.html.erbの3行目あたりと表示されています。 <h1>Editing Book</h1> <!-- form_with部分 --> <%= form_with model: @book, url: "/books/#{@book.id}", local:true do |f| %> <h4>Title</h4> <%= f.text_field :title %>  url: "/books/#{@book.id}”のidに問題がありそうなのですが、解決方法が絞れません。 ご教示いただけますと幸いです。
winterboum

2021/03/20 06:40

def update @book = Book.find(params[:id]) ですね・ このくらいは自力してよ
veludo

2021/03/20 07:19

ありがとうございます。解決しました。 お手数おかけして申し訳ありませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問