0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsでバリデーションでのエラーメッセージを分解してみる

Posted at

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

このような感じで、ササッとtitlebodyカラムを持ったpostsテーブルが作れました。
スクリーンショット 2021-02-04 175316.jpg

##作業準備2-バリデーションの設定

  • titleは空白はダメで、5文字以内
  • bodyは空白はダメ

というバリデーションを設定してみます。

post.rb
class Post < ApplicationRecord
  validates :title, presence: true, length: { maximum: 5 }
  validates :body, presence: true
end

これで
スクリーンショット 2021-02-04 180600.jpg
上記のようになり、条件を満たさない投稿は保存されません。
ところで、エラーメッセージを表示させるビューは

<% @post.errors.full_messages.each do |message| %>
  <li><%= message %></li>
<% end %>

のようになりますが、これを分解するのが、今回の本題となります。

##エラーメッセージの中身
gem pry-byebygを使って、エラーメッセージを見てみます。(インストール方法等は割愛)

posts_controller.rb
  
  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]でエラーメッセージを変更してみる

posts_controller.rb
  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

スクリーンショット 2021-02-04 184718.jpg
こんな風に変えてみたり…

###[2]でエラーメッセージにより遷移先を変えてみる

posts_controller.rb
  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

このように設定することで…(ルーティングは別途設定しています)
NewPost.gif

エラーメッセージに応じて、遷移先を変えることも出来ます。

おわりに

色々残して、自分が見直す機会になればいいなと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?