【Rails】 バリデーションエラーメッセージの出し方
はじめに
DBに値を保存する際(ユーザー登録やツイートの登録等)のバリデーションエラー文を表示するやり方について備忘録のために記載しておきます。
参考程度にどうぞ。
バリデーションとは?
バリデーションとはDBに値を保存する際に何か値が抜けていると保存できなくするものです。
簡単に言えばフィルターみたいなものですね。
例えばユーザー登録時にpasswordを入力してもらうとします。passwordが「111」とかだったらセキュリティーが甘くなりますね。
そこでバリデーションを記載してpasswordを8文字以上にしないと登録できないようにすれば、「111」と入力しても弾かれて保存できないようになります。
バリデーションの組み方は無数にあり、やり方を変えれば自分の思い通りに値を保存することができます。
例1)
モデルに下記のように記載すれば空では保存できません。
product.rb
class User < ApplicationRecord
validates :title, presence: true
end
例2)
モデルに下記のように記載すれば漢字のみ保存できるようになります。
product.rb
class User < ApplicationRecord
kanji = /\A[一-龥]+\z/
validates :name, format: { with: kanji }
end
例3)
モデルに下記のように記載すれば"2019-10-04"のような形でのみ保存できるようになります。
product.rb
class User < ApplicationRecord
year_month_day = /\A\d{4}-\d{2}-\d{2}\z/
validates :birthday, presence: true, format: { with: year_month_day }
end
バリデーションエラーメッセージの出し方
①商品の保存を行うアクション(ここではcreate)に保存の成功/失敗の条件分岐を記載。
ここで気をつけて欲しいのは失敗時のviewの読み込みはrenderを使用しましょう。
理由は後で解説します。
products_controller.rb
def create
@product = Product.new(product_params)
if @product.save
redirect_to controller: :products, action: :index
else
render "new"
end
end
②エラーメッセージのview作成
htmlのif文をmodel.errors.any? にしておくことでどのモデルのバリデーションにも対応させることができます。
layouts/_error_messages.html.erb
<% if model.errors.any? %>
<div class = "error">
<ul>
<% model.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
layouts/error_messages.scss
alert {
color:#262626;
background:#FFEBE8;
text-align: center;
border:2px solid #990000;
padding:12px; font-weight:850;
}
③エラーメッセージの表示
あとはエラーメッセージを表示させたいところに以下のコードを記載するだけです。
products/new.html.erb
<%= render 'layouts/error_messages', model: f.object %>
完成です。
こんな感じになります。めちゃめちゃ簡単です。
redirect_toとrenderの違い
先ほど、失敗時のviewの読み込みはrenderを使用すると記載しましたが、そこについて軽く触れます。
redirect_toとrenderはルーティングを通るか通らないかという違いがあります。
redirect_to…ルーティングを通り、新たにviewページを呼び出す。
render…ルーティングを通らず、viewページに飛ぶ。
正式にはもっと違いがありますが、とりあえずこの認識でOKです。
なので失敗時のviewの読み込み(以下の部分)をredirect_toにすると、
新しいビューページが呼ばれてしまうため、ページに書いたif文が反応しません。
products_controller.rb
def create
~省略~
else
render "new"
end
end
おわりに
特定のgem(例えばdeviseとか)には初めから実装されていることがあります。
ぜひ調べてみてください
この記事が気に入ったらサポートをしてみませんか?