こんにちは。
Ruby on RailsでWebアプリケーションサービスの開発をしています。
開発中にvalidatesエラーでrenderするも、renderした画面でエラーメッセージが表示されないという問題に陥りました。
今回その原因と解決方法についてご紹介します。
validatesエラー時にrenderしてもエラーメッセージが表示されない!
作りはまあシンプルで、user_controllerのcreateアクションに成功した時と失敗した時の処理を書いていました。
def create @user = User.new(user_params) respond_to do |format| if @user.save format.html { redirect_to top_path } else format.html { render 'setting' } end end end
ユーザーmodelでは、名前の未入力バリデーションを記述していました。
class User < ApplicationRecord validates :first_name, presence: true validates :last_name, presence: true
end
ユーザーが名前を未入力でsubmitした場合、バリデーションが走りエラーを返します。
byebugで止めながら処理を見ていきましたが、createアクションでは正常にelseに入っています。
render先のviewでは以下のような処理を書いていました。
<% if @user.errors.any? %> <p>エラーです!!!!!!!</p> <% end %>
ターミナルから確認しエラーであることも確認しました。
(byebug) @user.errors.any?
true
(byebug) @user.errors.full_messages
["Password can't be blank"]
ビューまでエラーが伝わっており、条件に合致しているにも関わらずエラーメッセージが表示されません。
なんでじゃ!!
validatesエラー時にrenderしてもエラーメッセージが表示されない! 解決方法
local: true をつける!
ユーザーのnameをsubmitする画面をform_withで作成していました。
<%= form_with model: @user do |f| %> <%= f.text_field :last_name, placeholder: "苗字" %> <%= f.text_field :first_name, placeholder: "名前" %>
<% end %>
form_withはデフォルトでremote: trueになっています。これがエラーメッセージ表示を阻害する原因でした。
Ajaxで処理をしたいわけではないので、明示的にlocal: trueを記述します。
<%= form_with model: @user, local: true do |f| %> <%= f.text_field :last_name, placeholder: "苗字" %> <%= f.text_field :first_name, placeholder: "名前" %>
<% end %>
form_withで作成した入力フォームにlocal: trueを記述した状態で、改めてsubmitします。
先ほど通りvalidateで弾かれて、エラーを抱えた状態で正常に条件分岐して、ビューまでたどり着き……
じゃん!
無事にrender先でバリデーションエラー時のメッセージを表示することができました!よかった〜〜!
validatesエラー時にrenderしてもエラーメッセージが表示されない! まとめ
ということで今回はRuby on Railsで、バリデーションエラー時にrenderした先でエラーメッセージが表示されない問題の解消方法についてご紹介しました。
form_withにまだ慣れていなくて結構苦戦してしまいました。
Railsのバージョンアップとともに便利になっていくメソッドたちですが、それが果たしてどういった処理をしているのかちゃんと紐解いてやらねばなりませんね。
同じようにバリデーションは効いているのにrender時にエラーメッセージが表示されなくてお困りの方の、参考になれば幸いです。
今回はここまで。