1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ウィザード形式でユーザ登録のフォームを作成してみた③-2 〜バリデーション(エラー表示)〜

Last updated at Posted at 2020-06-09

【この記事の説明】

現在、私はプログラミングスクールでプログラミング(主にRuby)の勉強をしています。
そして、その一環でチーム開発(メルカリもどきのサイト作成)を行っており、私はその中で記事のタイトルにあるように、ウィザード形式でユーザの登録ができるようにする作業を担当致しました。
又、スクールからの指示で、この登録フォームにはdeviseを使用するようにとのことでした。

この記事は、その担当作業についてまとめたものになります。

【作業】

ここから私が行った作業(そこで困ったこと)を記事として記載していこうと思います
※この記事では、バリデーションのエラー表示について記載したいと思います

エラー表示

今回のエラー表示には、deviseに元々あるファイルを使用したものと、それとは別に作成したファイルを使用したものの2種類があります

エラー表示を日本語表示にする
ユーザがエラーを読み易いように、日本語表示にする為、gemをインストールします
この時、必ず、Gemfileで、group :development do〜endgroup :test do~endの中に記述しないように気をつけます

/Gemfile
# deviseの日本語対応gem↓
gem 'devise-i18n'
gem 'devise-i18n-views'
# railsを日本語対応にする↓
gem 'rails-i18n'

deviseの場合
では、まずdeviseの場合です

devise.views.ja.ymlに必要な部分を追加します

/config/locales/devise.views.ja.yml
ja:
  activerecord:
    attributes:
      user:
        current_password: "現在のパスワード"
        email: "メールアドレス"
        password: "パスワード"
        password_confirmation: "確認用パスワード"
        remember_me: "ログインを記憶"
        # 追加部分↓
        nickname: "ニックネーム"
        family_name: "名字"
        given_name: "名前"
        family_name_kana: "名字(カナ)"
        given_name_kana: "名前(カナ)"
        birthday: "生年月日 "
        postal_code: "郵便番号"
        prefectures: "都道府県"
        city: "市区町村"
        address: "番地"
        building: "マンション名など"
        phone_number: "電話番号"
        # 追加部分↑
    models:
      user: "ユーザ"
      # 追加部分↓
      profileaddress: "ご本人様情報入力(任意)"
      deliveryaddress: "お届け先入力"
      # 追加部分↑
  devise:
    confirmations:
      new:
        resend_confirmation_instructions: "アカウント確認メール再送"
    mailer:
      confirmation_instructions:
        action: "アカウント確認"
        greeting: "ようこそ、%{recipient}さん!"
        instruction: "次のリンクでメールアドレスの確認が完了します:"
      reset_password_instructions:
        action: "パスワード変更"
        greeting: "こんにちは、%{recipient}さん!"
        instruction: "誰かがパスワードの再設定を希望しました。次のリンクでパスワードの再設定が出来ます。"
        instruction_2: "あなたが希望したのではないのなら、このメールは無視してください。"
        instruction_3: "上のリンクにアクセスして新しいパスワードを設定するまで、パスワードは変更されません。"
      unlock_instructions:
        action: "アカウントのロック解除"
        greeting: "こんにちは、%{recipient}さん!"
        instruction: "アカウントのロックを解除するには下のリンクをクリックしてください。"
        message: "ログイン失敗が繰り返されたため、アカウントはロックされています。"
    passwords:
      edit:
        change_my_password: "パスワードを変更する"
        change_your_password: "パスワードを変更"
        confirm_new_password: "確認用新しいパスワード"
        new_password: "新しいパスワード"
      new:
        forgot_your_password: "パスワードを忘れましたか?"
        send_me_reset_password_instructions: "パスワードの再設定方法を送信する"
    registrations:
      edit:
        are_you_sure: "本当に良いですか?"
        cancel_my_account: "アカウント削除"
        currently_waiting_confirmation_for_email: "%{email} の確認待ち"
        leave_blank_if_you_don_t_want_to_change_it: "空欄のままなら変更しません"
        title: "%{resource}編集"
        unhappy: "気に入りません"
        update: "更新"
        we_need_your_current_password_to_confirm_your_changes: "変更を反映するには現在のパスワードを入力してください"
      new:
        sign_up: "アカウント登録"
    sessions:
      new:
        sign_in: "ログイン"
    shared:
      links:
        back: "戻る"
        didn_t_receive_confirmation_instructions: "アカウント確認のメールを受け取っていませんか?"
        didn_t_receive_unlock_instructions: "アカウントの凍結解除方法のメールを受け取っていませんか?"
        forgot_your_password: "パスワードを忘れましたか?"
        sign_in: "ログイン"
        sign_in_with_provider: "%{provider}でログイン"
        sign_up: "アカウント登録"
    unlocks:
      new:
        resend_unlock_instructions: "アカウントの凍結解除方法を再送する"

viewでエラーを呼び出すコードを記述します
ここで、deviseの記載そのままだと= form_withの下に= renderの形ですでに記述されています
この記述により、エラー用のファイルが呼び出されて、このview(new.html.haml)のエラーが全て上に表示されますが、今回は入力フォーム毎にエラーを表示したいので、この記述= renderは削除します

そして、入力フォーム下に- if @user.errors.any?を記述し、エラー表示を入力フォーム下にするようにします
ちなみに、この- if @user.errors.any?の記述内容は、/app/views/users/shared/_error_messages.html.hamlをほぼ引用したものであり、異なっているのは、- @user.errors.full_messages_for(:nickname).each do |message|の部分となります

full_messages_for(xxx)は特定の属性(xxx)のエラーメッセージのみを取得するメソッドであり、この場合は:nicknameに関するエラーメッセージのみ表示するということになります

/app/views/users/registrations/new.html.hamlから必要部分のみ抜粋
.login-main__title
      会員情報入力
    .login-main__content
      .login-main__content__form
        = form_with(model: @user, url: profileaddresses_path,local: true,method: :post) do |f|  
        # = render "devise/shared/error_messages", resource: resource
        # deviseの記載そのままだと上のコードがあるが、ここにあると全てのエラーがフォームの一番上に表示されてしまう為、削除
.form-group
            ニックネーム
            %span.required
              必須
            %br
            .field
              = f.text_field :nickname, autofocus: true, autocomplete: "nickname",placeholder: "例)フリマ太郎",class: "default" 
              # ここから↓記述           
              - if @user.errors.any?
                .error_explanation
                  %h2
                    - I18n.t("errors.messages.not_saved",                 |
                      count: resource.errors.count,                       |
                      resource: resource.class.model_name.human.downcase) |
                  %ul
                    - @user.errors.full_messages_for(:nickname).each do |message|
                      %li{style: "color:red"}
                        = message
               # ここまで↑記述
/app/views/users/shared/_error_messages.html.haml
- if resource.errors.any?
  #error_explanation
    %h2
      = I18n.t("errors.messages.not_saved",                 |
        count: resource.errors.count,                       |
        resource: resource.class.model_name.human.downcase) |
    %ul
      - resource.errors.full_messages.each do |message|
        %li= message

= form_withの下
スクリーンショット 2020-05-29 5.36.14.png

入力フォーム下
スクリーンショット 2020-06-08 5.36.45.png

deviseを使用できない場合
/config/locales/ja.ymlに必要部分を追加します

/config/locales/ja.yml(追加部分のみ記載)
ja:
  activerecord:
    # 追加部分↓
    profileaddresses:
      postal_code: '郵便番号'
      prefectures: '都道府県 '
      city: '市区町村'
      address: '番地'
      building: 'マンション名など'
    deliveryaddresses:
      family_name: "名字"
      given_name: "名前"
      family_name_kana: "名字(カナ)"
      given_name_kana: "名前(カナ)"
      birthday: "生年月日 "
      postal_code: '郵便番号'
      prefectures: '都道府県 '
      city: '市区町村'
      address: '番地'
      building: 'マンション名など'
      phone_number: '電話番号'
    # 追加部分↑
    errors:
      messages:
        record_invalid: 'バリデーションに失敗しました: %{errors}'
        restrict_dependent_destroy:
          has_one: "%{record}が存在しているので削除できません"
          has_many: "%{record}が存在しているので削除できません"

バリデーションを日本語使用にする為に、I18n.t(User.human_attribute_name(xxx))を使います

/app/models/deliveryaddress.rb(必要部分のみ抜粋)
  def name_em
    @error_name1 = I18n.t(User.human_attribute_name(:family_name))
    # I18n.t(User.human_attribute_name(:family_name)) = Translation missing: ja 名字
    @error_name2 = I18n.t(User.human_attribute_name(:given_name))
    # I18n.t(User.human_attribute_name(:given_name)) = Translation missing: ja 名前
    if !(family_name =~ /^[ぁ-んァ-ン一-龥]/)
      if !(given_name =~ /^[ぁ-んァ-ン一-龥]/)
        errors.add @error_name1, "は全角で入力してください"
        errors.add @error_name2, "は全角で入力してください"
      else
        errors.add @error_name1, "は全角で入力してください"
      end
    elsif !(given_name =~ /^[ぁ-んァ-ン一-龥]/)
      errors.add @error_name2, "は全角で入力してください"
    else
      return
    end
  end

そのままエラーメッセージを表示すると"Translation missing: ja"という言葉が表示されてしまうので、それを削除するコードを記述をします

/app/views/users/registrations/new_deliveryaddresses.html.haml(必要部分のみ抜粋)
  .login-main
    .login-main__title
      お届け先住所入力
    .login-main__content
      .login-main__content__form
        = form_with(model: @deliveryaddress,url: user_registration_path,local: true) do |f|
          
          .form-group
            お名前(全角)
            %span.required
              必須
            %br
            .field
              = f.text_field :family_name, autofocus: true, autocomplete: "family_name",placeholder: "例)山田",class: "default half"           
              = f.text_field :given_name, autofocus: true, autocomplete: "given_name",placeholder: "例)太郎",class: "default half__right"       
              -if @deliveryaddress.errors.any?
              # @deliveryaddressは/app/models/deliveryaddress.rbのこと
                .alert.alert-warning
                  %ul
                    - @deliveryaddress.errors.full_messages.each do |message|
                      %li{style: "color:red"} 
                        - if message.include?("名字は")
                        # エラーメッセージ内に”名字はという言葉が入っている時は”
                          = message.delete!("Translation missing: ja")
                        # エラーメッセージ文の中から"Translation missing: ja"を削除する
                        # エラーメッセージが「Translation missing: ja 名字は全角で入力してください」が「名字は全角で入力してください」になる
              -if @deliveryaddress.errors.any?
                .alert.alert-warning
                  %ul
                    - @deliveryaddress.errors.full_messages.each do |message|
                      %li{style: "color:red"} 
                        - if message.include?("名前は")
                         # エラーメッセージ内に”名前はという言葉が入っている時は”
                          = message.delete!("Translation missing: ja")
                         # エラーメッセージ文の中から"Translation missing: ja"を削除する
                         # エラーメッセージが「Translation missing: ja 名前は全角で入力してください」が「名前は全角で入力してください」になる

```= form_withの下``
スクリーンショット 2020-05-29 5.39.49.png

入力フォーム下
スクリーンショット 2020-05-31 21.08.02.png

###【参考】
【Rails】バリデーションエラーをそのインプットフィールドの近くに1つだけ表示したかった。
あなたはいくつ知っている?Rails I18nの便利機能大全!
Rails】バリデーションのエラーメッセージを取得・表示・日本語化する方法を完全解説!

1
4
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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?