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

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

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

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Ruby on Rails

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

Q&A

解決済

1回答

590閲覧

NoMethodErrorが治らない

yukitodesu3

総合スコア10

Cloud9

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Ruby on Rails

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

0グッド

1クリップ

投稿2021/02/06 00:46

前提・実現したいこと

railsでデータベースを使ったbookアプリを作っています。
フォームの中身が空の時エラーの文字が出るバリエーションをを作りたいのですが、エラーが起き前に進みません。

イメージ説明

該当のソースコード

books_controller.rb

class BooksController < ApplicationController def index end def show @book = Book.find(params[:id]) end def new # Viewへ渡すためのインスタンス変数に空のモデルオブジェクトを生成する。 @book = Book.new @books = Book.all end def edit @book = Book.find(params[:id]) end def books end def create book = Book.new(list_params) if book.save redirect_to book_path(book.id) else @books = Book.new render 'new' end end def update book = Book.find(params[:id]) if book.update(list_params) redirect_to book_path(book.id) else render 'new' end end def destroy book = Book.find(params[:id]) book.destroy redirect_to books_path end private def list_params params.require(:book).permit(:title, :body) end end

new.html.erb

<main> <!-- form_with部分 --> <%= form_with model: @book,local:true do |f| %> <% if @book.errors.any? %> <p>エラーです</p> <% end %> <% @books.each do |book| %> <div id="main-title"> <h4>Books</h4> </div> <table> <div id="book-index"> <thead> <tr> <th>Title</th> <th>body</th> <th></th> </th> </thead> <tr><span><%= book.title %></span></tr> <tr><span><%= book.body %></span></tr> <tr><%= link_to 'Show', book_path(book) %></tr> <tr><%= link_to 'Edit', edit_books_path(book.id) %></tr> <tr><%= link_to "delete", book_path(book), method: :delete, data:{confirm:'Are you sure?'}%></tr> <% end %> </div> </table> <div class="main-item"> <div class="main-logo"> <h1>New book</h1> </div> <div class="main-list"> <h4>title</h4> <%= f.text_field :title %> </div> <div class="main-list2"> <h4>body</h4> <%= f.text_area :body %> <%= f.submit '投稿' %> <% end %> </div> </div> </main>

book.rb

class Book < ApplicationRecord validates :title, presence: true validates :body, presence: true,length: {minimum: 5} end

試したこと

rails初心者でbook.controllerの中身をいじってみたり、変数を変えてみたりしたのですが、解決しませんでした。回答よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

# books_controller.rb def create book = Book.new(list_params) if book.save redirect_to book_path(book.id) else @books = Book.new render 'new' end end ↓ def create @book = Book.new(list_params) if @book.save redirect_to book_path(book.id) else @books = Book.all render 'new' end end

これで直りませんでしょうか。


解説しておきますね。

エラーメッセージ(ブラウザの翻訳機能を有効にしているんだと思いますが、質問するときはoffのものを貼った方が良いかもしれません)から、

<% if @book.errors.any? %>

の箇所で、 @book が nil になっているせいで発生しているエラーだということがわかります。
create アクションで new ビューを表示させているので、入力内容不備によるヴァリデーションエラーを出したい状況だとわかりますが、このときは @book に入力内容が保持されている必要があり、 nil になっているのはおかしいです。

で、んじゃ new ビューに @book を渡している create アクションの中身を見てみます。
慣れている人だと一発で分かりますが、 list_params を受け取っているのはいいけどこれが単なるローカル変数になってます。これだと create アクション内部でしか有効じゃ無いので、new アクションに引き継がれません。
正常系、つまり入力内容が正しくで正常にデータを登録できる場合はこれで動作しますが、異常系の場合は new ビューに必要な @book を初期化してないし値を渡してもいないので、エラーに繋がっています。

実は同じ問題は update アクションでも起こるはず。
こちらでも book -> @book にしておくと全く同じように解消できると思います。

大丈夫だと思うんですが、これで直らなかったらまた言ってください。

投稿2021/02/06 02:16

編集2021/02/06 02:32
oakbow

総合スコア227

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

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

yukitodesu3

2021/02/06 02:37

エラー治りました。 ありがとうございます。 newアクションを引き継げてなかったんですね 勉強になります。
oakbow

2021/02/06 02:41

URL(と動詞)ごとに実行されるアクションは決まっているので、new アクションを引き継ぐことはできないです。あくまで入力パラメータをビューに渡すというアクションの役目を果たせていなかったのが問題だったわけですね。
yukitodesu3

2021/02/07 13:37

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問