Railsでajax通信時にattribute名とfull_messageの組み合わせでレスポンスを返す
ajaxでの非同期通信時に、attributeごとのメッセージを表示するのに手間取ったので記録しておきます。
ajax通信でない時は、errors.full_messages_for(:attribute_name)で各attributeのエラーメッセージは取得できます。
やりたいこと
ajax通信時に、入力エラーがある場合に、入力項目ごとに表示したい。
こうなればよい。
errorsを使用する場合(うまくいかなかった例)
コード
class TicketsController < ApplicationController def create ticket = Ticket.create(ticket_params) if ticket.save render json: {message: 'success'}, status: :created else error_messages = ticket.errors render json: {message: error_messages}, status: :unprocessable_entity end end end
レスポンス
{"message": {"password":["を入力してください"], "email":["を入力してください","は有効でない形式です"]} }
画面表示
メッセージボディしか表示されません。これじゃない。
errors.full_messages を使用する場合(うまくいかなかった例)
コード
class TicketsController < ApplicationController def create ticket = Ticket.create(ticket_params) if ticket.save render json: {message: 'success'}, status: :created else error_messages = ticket.errors.full_messages render json: {message: error_messages}, status: :unprocessable_entity end end end
レスポンスはこのようになります。
{"message":["パスワードを入力してください","メールアドレスを入力してください","メールアドレスは有効でない形式です"]}
画面に表示するとしたらこうなります。
1ヶ所に全てのエラーを表示する場合はこれでもよいですが、項目ごとに表示するといった目的は達成できません。
ticket.errors.keys と errors.full_messages_for 組み合わせる(うまくいった例)
コード
class TicketsController < ApplicationController def create ticket = Ticket.create(ticket_params) if ticket.save render json: {message: 'success'}, status: :created else error_messages = ticket.errors.keys.map { |key| [key, ticket.errors.full_messages_for(key)]}.to_h render json: {message: error_messages}, status: :unprocessable_entity end end end
レスポンス
{"message": {"password":["パスワードを入力してください"], "email":["メールアドレスを入力してください","メールアドレスは有効でない形式です"]} }
画面表示
できました!