【Ruby on Rails】ログから確認する"status::unprocessable_entity"が必要な理由
はじめに
Ruby on Railsでフラッシュメッセージ、バリデーションのエラーメッセージを出力する際の挙動で、少し理解が浅い部分がありましたので備忘録として記載したいと思います。
具体的には、renderメソッド使用時になぜstatus::unprocessable_entity
が必要なのかという内容になります。
今回、フラッシュメッセージ、バリデーションエラー出力に関する実装の説明は省略させていただきます。
参考になりましたら幸いです。
環境
Rails 7.1.3.4
ログ上で"status::unprocessable_entity"の有無を確認する
"status::unprocessable_entity"の記載がない場合
当初ユーザーの新規登録時、createアクション内の新規登録に失敗した際には、render :new
のみ記載していました。
下記がその時のコード、実際のアプリ画面、サーバーログになります。
- app/controllers/users_controller.rb
class UsersController < ApplicationController
skip_before_action :require_login, only: [:new, :create]
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to articles_path, notice: '新規登録が完了しました。'
# sorceryのオートログイン機能
auto_login(@user)
else
flash[:alert] = '新規登録に失敗しました'
render :new
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
GIF上でも、エラーメッセージ、バリデーションエラーが発生していないことがわかります。
サーバーログを確認してみると、なぜエラーメッセージ、バリデーションエラーが発生していないかが理解できました。
サーバーログの一番下にCompleted 200 OK
の記載が出ていることが確認できます。
MDNにも記載がある通り、
HTTP 200 OK はリクエストが成功した場合に返すレスポンスコード。
のため、クライアントへ正常なリクエストが渡っていると誤認させてしまっています。
"status::unprocessable_entity"を記載した場合
何故エラーメッセージ、バリデーションエラーが出ないかを模索したところ、こちらの記事を拝見、renderメソッドの後ろに status: :unprocessable_entity
を追記しました。
すると、画面上でもエラーメッセージとともにバリデーションエラーが出力されていることが確認できました。
(パスワードは最小8文字以上で設定しているため、5文字で入力しバリデーションエラーを出力させました)
- app/controllers/users_controller.rb
class UsersController < ApplicationController
skip_before_action :require_login, only: [:new, :create]
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to articles_path, notice: '新規登録が完了しました。'
# sorceryのオートログイン機能
auto_login(@user)
else
flash[:alert] = '新規登録に失敗しました'
render :new, status: :unprocessable_entity
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
GIF上でも、エラーメッセージ、バリデーションエラーが発生していることがわかります。
サーバーログの一番下にCompleted 422 Unprocessable Content
の記載が出ていることが確認できます。
MDNにも記載がある通り、
The HyperText Transfer Protocol (HTTP) の 422 Unprocessable Entity 応答状態コードは、サーバーが要求本文のコンテンツ型を理解でき、要求本文の構文が正しいものの、中に含まれている指示が処理できなかったことを表します。
と記載があります。
status::unprocessable_entity
を追記することで、クライアント側が、エラーが発生したことキャッチできるステータスコードへ変わったのです。
まとめ
Railsガイドを確認してみても、こちらはRails7系から必須になっているようでした。(6系のRailsガイドには記載なし)
Railsガイドではstatus: :unprocessable_entity
の具体的な記載が見受けられず、今回は個人記事を参照させていただきました。
スクールのカリキュラムで学習時は、なんとなくstatus: :unprocessable_entity
をrenderメソッドの後ろに追記していました。
今回ログから確認してみることで、なぜstatus: :unprocessable_entity
を追記する必要があるのか、その役割を確認することができました。
ありがとうございました。
Discussion