0
0

More than 1 year has passed since last update.

validatesのエラーメッセージを表示する仕組み

Posted at

環境

Rails 5.2

内容

validatesのチェックで引っかかった場合、どのような仕組みでエラーが表示されているのか、確認してみました。

userモデルには、namename_idの2つのカラムがあり、次のようにvalidatesチェックをかけています。

user.rb
validates :name,    presence: true
validates :name_id, presence: true, uniqueness: true

editで編集画面を表示して、nameを空白にし、name_idに重複したデータを入力して、更新ボタンを押します。すると、コントローラのupdateメソッドに入ります。validatesのチェックは、@user.updateが実行されるタイミングで行われます。validatesのチェックで引っかかった場合、@user.updateの戻り値がfalseで返ってくるため、if文のelseに入ります。flashには「更新が失敗しました。」と表示されますが、具体的に、どの項目がどのような理由で更されなかったのかといった情報までは、このメッセージだけでは分かりません。

users_controller.rb
def update
	@user = User.find(params[:id])
    if @user.update(user_params)
        flash[:notice] = "更新しました。"
        redirect_to master_user_url
    else
        flash[:notice] = "更新が失敗しました。"
        render :edit
    end
end

@userオブジェクトのerrorsに、エラーに関する詳細な情報がセットされます。次の変数を使って拾うことができます。full_messagesを使うと、エラーが複数ある場合、全てのエラーを配列で取得することができます。


@user.errors.full_messages          => ["名前を入力してください", "ユーザーIDはすでに存在します"]

項目名だけを指定すると、次のような取得のされ方をします。

@user.errors.messages[:name]        => ["を入力してください"]
@user.errors.messages[:name_id]     => ["はすでに存在します"]

validatesチェックのエラーメッセージはデフォルトで英語になっています。日本語に変換するために、ja.ymlファイルを次のように作成します。未入力エラーの場合は、「blank⇒を入力してください」に、重複チェックの場合は、「taken⇒はすでに存在します」にそれぞれ変換されます。変換後、エラーメッセージはformatの形式で出力されます。

config/locales/ja.yml
ja:
  activerecord:
      attributes:
          master/user:
            name: 名前
            name_id: ユーザーID
  errors:
    format: "%{attribute}%{message}"
    messages:
       blank: を入力してください
       taken: はすでに存在します

配列にセットされたエラーメッセージは、eachで1個づつ取り出して画面表示します。presentを付けることで、errorsにエラーメッセージが存在するときだけ、画面表示することができます。

_from.html.slim
- if full_messages user.errors.present?
    ul#error_explanation
        - user.errors.each do |msg|
            li = msg
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0