yucatio@システムエンジニア

趣味で作ったものいろいろ

Railsでajax通信時にattribute名とfull_messageの組み合わせでレスポンスを返す

ajaxでの非同期通信時に、attributeごとのメッセージを表示するのに手間取ったので記録しておきます。

ajax通信でない時は、errors.full_messages_for(:attribute_name)で各attributeのエラーメッセージは取得できます。

やりたいこと

ajax通信時に、入力エラーがある場合に、入力項目ごとに表示したい。

こうなればよい。

f:id:yucatio:20170414023228p:plain:w400

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":["を入力してください","は有効でない形式です"]}
}

画面表示

f:id:yucatio:20170414023247p:plain:w400

メッセージボディしか表示されません。これじゃない。

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":["パスワードを入力してください","メールアドレスを入力してください","メールアドレスは有効でない形式です"]}

画面に表示するとしたらこうなります。

f:id:yucatio:20170414023306p:plain:w400

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":["メールアドレスを入力してください","メールアドレスは有効でない形式です"]}
}

画面表示

f:id:yucatio:20170414023228p:plain:w400

できました!

環境