rails フォームでよく使われるエラーメッセージパーシャルなど作成
実現すること
フォームに何も入力されてない状態で投稿ボタン押すなどするとアラートが出るやつです。
方法
例としてProductモデルを使います。バリデーションは下記の通り↓
product.rb class Product < ApplicationRecord validates :name, presence: true, length:{ maximum: 50} validates :price, presence: true, length:{ maximum: 20}, format: /\A[0-9]+\z/ validates :description, presence: true, length:{ maximum: 200} validates :picture, presence: true end
空なし、文字数制限、フォーマットの指定などを設定しています。
これでモデル(model)でバリデーションエラーが発生した場合に、model の errorsにエラーメッセージが設定されます。
コントローラー↓
products_controller.rb def create @product = Product.new(product_params) if @product.save (省略) else #バリデーションエラーがあればフォームに戻る render 'new' end end
パーシャル作成
_error_messages.html.erb <% if object.errors.any? %> <div id="error_explanation"> <div class="alert alert-danger"> <%= object.errors.count %>つのエラー! 入力に誤りがあります。 </div> <ul> <% object.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %>
renderでフォームにエラーメッセージのパーシャルを追加
今回はform_forを使っています。
<div class="form"> <%= form_for(@product) do|f| %> #error_messages.html.erbを呼び出す <%= render'error_messages',object: f.object %> <div class="form-group"> <%= f.label "商品名" %> <%= f.text_field :name ,class: 'form-control' %> </div> <div class="form-group"> <%= f.label "定価" %> <%= f.text_field :price ,class: 'form-control' %> </div> (中略) <%= f.submit '投稿する', class: "submit-btn" %> <% end %> </div>
コントローラーの動きの通りバリデーションエラーがでた場合には、フォーム画面に戻ります。
そこでif文でエラーがあると認識され、error_explanation要素が表示されます。object.errorsには発生したエラーが含まれているので、object.errors.countとすれば「エラーの数」、object.errors.full_messagesはエラーメッセージを配列で持っているので、eachメソッドで順番に表示しています。
メッセージを日本語化したい場合は、こちらの記事を参考に設定しましょう。
Railsのバリデーションエラーのメッセージの日本語化 - Qiita
設定ができたらProductモデル用のja.ymlを作成
ja.yml ja: activerecord: models: product: 商品 attributes: product: id: ID created_at: 登録日時 updated_at: 更新日時 name: 商品名 price: 定価 description: 説明 picture: 画像
あとはエラーメッセージの見た目を整えます。
//Alert #error_explanation { color: red; ul { list-style-position: inside; color: red; margin: 0 0 30px 0; } } .field_with_errors { .form-control { border-color: #ebccd1; } } .alert { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } .alert-danger { color: #a94442; background-color: #f2dede; border-color: #ebccd1; }
form_forを使っていて、バリデーションエラーが発生すると全てのフィールドにfield_with_errorsを追加するのでその時にそれぞれのフォームの枠線を赤っぽくしています。
これでフォームで入力なし、文字の制限を超える、フォーマットが違うなどのエラーを拾ってメッセージが表示されるようになります!