2回目の投稿となります
自分の見直しとして、もっと上手に使っていきたいですね!
##これ is 何
保存されなかった時にエラーメッセージを表示させるやり方、というものは調べれば割とすぐ出てきますが、その内容に応じて動作を変化させるときに用いました。
##開発環境
ruby 2.6.3
Rails 5.2.4.4
##作業準備1-MVC他作成
$ rails new sample_app
$ cd sample_app
$ rails g scaffold post title:string body:text
$ rails db:migrate
このような感じで、ササッとtitle
とbody
カラムを持ったposts
テーブルが作れました。
##作業準備2-バリデーションの設定
-
title
は空白はダメで、5文字以内 -
body
は空白はダメ
というバリデーションを設定してみます。
class Post < ApplicationRecord
validates :title, presence: true, length: { maximum: 5 }
validates :body, presence: true
end
これで
上記のようになり、条件を満たさない投稿は保存されません。
ところで、エラーメッセージを表示させるビューは
<% @post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
のようになりますが、これを分解するのが、今回の本題となります。
##エラーメッセージの中身
gem pry-byebyg
を使って、エラーメッセージを見てみます。(インストール方法等は割愛)
def create
@post = Post.new(post_params)
if @post.save
redirect_to post_path(@post.id)
else
binding.pry #この位置
render :new
end
end
[1] pry(#<PostsController>)> @post.errors.messages
=> {:title=>["is too long (maximum is 5 characters)"], :body=>["can't be blank"]}
[2] pry(#<PostsController>)> @post.errors.full_messages
=> ["Title is too long (maximum is 5 characters)", "Body can't be blank"]
このような結果になりました。先程のビューでは、[2]の結果の配列をeachで出力している、ということが分かりました。これを元に、色々試してみます。
###[1]でエラーメッセージを変更してみる
def create
@post = Post.new(post_params)
if @post.save
redirect_to post_path(@post.id)
else
@post.errors.messages[:body] = ["は空欄には出来ません。"] #追加
render :new
end
end
###[2]でエラーメッセージにより遷移先を変えてみる
def create
@post = Post.new(post_params)
if @post.save
redirect_to post_path(@post.id)
else
if @post.errors.full_messages.any? { |t| "Title can't be blank".include?(t) }
redirect_to titleblank_path
elsif @post.errors.full_messages.any? { |t| "Title is too long (maximum is 5 characters)".include?(t) }
redirect_to titletoolong_path
else
redirect_to bodyblank_path
end
end
end
このように設定することで…(ルーティングは別途設定しています)
エラーメッセージに応じて、遷移先を変えることも出来ます。
おわりに
色々残して、自分が見直す機会になればいいなと思います。