質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.12%

【rails】【devise】新規登録画面にアクセスした段階で入力エラーの内容が表示される

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,904

gogoackman3

score 101

表題の通り、新規登録画面への初回アクセス時点で既にフォームのエラー内容が表示されます。

当然、初回アクセス時点ではフォームに何も入力されていないので、それでバリデーションがかかると、「空です」「何文字以上にしてください」などすべてのバリデーションに引っかかります。

ログイン画面だと初回アクセス時点ではフォームのエラーは表示されないのですが、何故か分かりかねています・・・。

(もし分かれば追加で、)ログイン画面では、フォームでのエラーが「メールアドレスまたはパスワードが違います。」となるのですが、「メールアドレス/ユーザーIDまたはパスワードが違います。」と変更するにはどうすれば良いのでしょうか??

※ruby 2.3.1p11/Rails 5.0.0.1

▼新規登録画面

section.signup_area

  = form_for(resource, as: resource_name, url: user_registration_path) do |f|
    .form_item
      label 
        = image_tag('icon_mail.png')
        | メールアドレス
      = f.email_field :email, autofocus: true, class: 'register_info',  placeholder: '有効なメールアドレスを入力', 'aria-required': 'true', size: 30
      = error_message(resource, :email)

    .form_item
      label 
        = image_tag('icon_key.png')
        | パスワード
      = f.password_field :password, autocomplete: "off", class: 'register_info', placeholder: '半角英数字混合で6文字以上', 'aria-required': 'true', size: 30
      = error_message(resource, :password)

    p.terms_link 
      |  登録すると
      = link_to '利用規約', terms_of_use_path
      | 及び
      = link_to 'プライバシーポリシー', privacy_policy_path
      |に同意したことになります

    div
      = f.submit 'この内容で新規登録'

▼ヘルパーerror_message

module ApplicationHelper

  def error_message(resource, attr_name)
    if resource.errors[attr_name].present?
      %Q(<p class="error">#{ resource.errors.full_messages_for(attr_name).join('<br>')}</p>)
    end.to_s.html_safe
  end
end

▼新規登録のController

class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]

  prepend_before_action :authenticate_scope!, only: [:edit_detail, :update_detail]


  # GET /resource/sign_up
  def new
    super
  end

   def edit_detail

  end

  def update_detail
    resource_updated = resource.update(detail_params)
    if resource_updated
      @modal = {name: 'update-detail-modal'}
    end
    render :edit_detail
  end

  protected

    # If you have extra params to permit, append them to the sanitizer.
    # def configure_sign_up_params
    #   devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
    # end

    # If you have extra params to permit, append them to the sanitizer.
    # def configure_account_update_params
    #   devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
    # end

    def detail_params
      params.require(:user).permit(:icon, :handle_name, :profile)
    end

end

▼ログイン画面

section.login_area
  - if flash[:alert].present?
    p.error = flash[:alert]

  = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
    .form_item
      label 
        = image_tag 'icon_mail.png' 
        |  メールアドレス/ユーザー名
      = f.text_field :login, autofocus: true, class: 'register_info', placeholder: 'メールアドレスまたはユーザー名を入力', 'aria-required': true, size: 30
      = error_message(resource, :login)

    .form_item
      label 
        = image_tag 'icon_key.png'
        |  パスワード
      = f.password_field :password, autocomplete: "off", class: 'register_info', placeholder: '半角英数字混合で6文字以上', 'aria-required': true, size: 30
      = error_message(resource, :password)
    div
      = f.submit 'ログイン'

  p.fogot_pass
    = link_to 'パスワードをお忘れの方はこちら', new_password_path(resource_name)

▼ログインのController

class Users::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]

  # GET /resource/sign_in
  def new
    super
  end

end

▼user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, omniauth_providers: [:twitter],authentication_keys: [:login]

  # ログイン時のIDをメアドとhandle_nameの両対応
  attr_accessor :login

  validates :email,    format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i }, length: { maximum: 255 }, on: :create
  validates :password, format: { with: /\A[0-9a-z]+\z/i                     }, length: { minimum:   6 }, on: :create
  validates :handle_name, length: { minimum:3, maximum:15 }, format: { with: /\A[a-zA-Z0-9_]+\z/, message: "ユーザー名は半角英数字またはアンダーバー(_)のみ利用可能です。"}

  with_options if: :persisted? do |user|
    user.validates :handle_name, presence: true
    user.validates :handle_name, length: { maximum:  15 }
    user.validates :profile,     length: { maximum: 100 }
    user.validates :email,       confirmation: true
  end

  # mount_uploader :icon, IconUploader

  def self.from_omniouth(auth)
    where(provider: auth["provider"], uid: auth["uid"]).first_or_create do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.username = auth["info"]["nickname"]
    end
  end

  def self.new_with_session(params,session)
    if session["devise.user_attributes"]
      new(session["devise.user_attributes"]) do |user|
        user.attributes = params
        user.valid?
      end
    else
      super
    end
  end

  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditons.delete(:login)
      where(conditions).where(["handle_name = :value OR lower(email) = lower(:value)", { :value => login }]).first
    else
      where(conditions).first
    end
  end
end
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

# user.rb

session["devise.user_attributes"]


に何か値が入ってしまっているのでは無いでしょうか?

その場合、新規登録のコントローラーの

def new
    super
  end


super

# user.rb
  def self.new_with_session(params,session)
    if session["devise.user_attributes"]
      new(session["devise.user_attributes"]) do |user|
        user.attributes = params
        user.valid?
      end
    else
      super
    end
  end


が呼ばれるため、
user.valid?が走り、errorがセットされた状態でformに渡ってしまいます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/22 01:09

    ありがとうございます! self.new_with_sessionの部分をコメントアウトすると確かに初回アクセス時にエラーメッセージが表示されなくなりました!
    やりたいことはTwitterログインとメアドログインを両方実装したく、そのため、前述のメソッドを定義していました。

    また、再度調べて考えてみたいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる