##はじめに
Railsで、バリデーションによるエラーメッセージの表示をしようとしたら
エラーが出てしまい、調べてみたらとても初歩的なミスを犯していたので
忘れないよう、エラーメッセージ表示の手順を、自分用のメモみたいな感じでまとめました!
##手順
「新規投稿」を例にとることにします。
まず、新規投稿が行われる手順から
順を追って、バリデーションによるエラーメッセージの表示方法について説明していきます。
1.まずは、modelフォルダの中のpost.rbファイルの中で、バリデーションを設定します。
これによってバリデーションに弾かれたデータには自動でエラーメッセージが取得されます。
class Post < ApplicationRecord
validates :content, presence: true,
length: {maximum: 140}
end
2.「new.html.erb」で投稿ボタンを押すと、form_tagで指定したURL("/posts/create")へデータが送信されます
<%= form_tag("/posts/create") do %>
<textarea name="content"> </textarea>
<input type="submit" value="投稿">
<% end %>
3.送信されたデータをルーティングで取得し、createアクションへ
post "posts/create" => "posts#create"
4.送信されて来たデータの保存が完了した場合→("/posts/index")画面へ。 バリデーションに弾かれ、保存されなかった場合→再び("/posts/new")画面へ転送する。
def create
@post = Post.new(content: params[:content])
if @post.save
redirect_to("/posts/index")
else
render("posts/new")
end
end
この後、データベースに保存された全ての投稿データを取得し、繰り返し処理によりビューで表示することで、投稿が一つずつ表示されるわけですが
私は、バリデーションに弾かれたエラーメッセージの取得が、手順3の段階でされるのだと思っていました。
それゆえ、以下のように3の手順で取得した@postから、エラーメッセージを表示させようとしたら
<% @post.errors.full_messages.each do |message| %>
<%= message %>
<% end %>
「undefined method `errors' for nil:NilClass」
といったように、エラーメッセージが定義されてませんと怒られてしまいました…ごめんなさい…。
何故取得できないのかというと、2の手順でバリデーションに弾かれたデータは
newアクションへ転送され、__newアクションで取得する必要がある__からでした。
つまり、弾かれたデータは直前のアクションに送信されます。
しかし、それ以前に「new.html.erb」で「createアクションで定義した変数」を使えるわけないのですから当然でした……
(ただしrenderで転送した場合は、そのまま変数の転送も行ってくれる)
ですので、以下のように、newアクションで変数を定義してあげることで
ここに、バリデーションで弾かれたデータが作成されるようになります。
def new
@post = Post.new
end
あとは、「new.html.erb」で、エラーメッセージを表示するためのコードを書いてあげれば ちゃんとエラーメッセージが表示されるようになるはずです。
<% @post.errors.full_messages.each do |message| %>
<%= message %></p>
<% end %>