为什么设计不在登录页面上显示身份validation错误?

我正在使用rails 4.2

我有一个名为devise_helper.rb的帮助文件

module DeviseHelper def devise_error_messages! return "" if resource.errors.empty? messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join sentence = I18n.t("errors.messages.not_saved", count: resource.errors.count, resource: resource.class.model_name.human.downcase) html = <<-HTML 

#{sentence}

    #{messages}
HTML html.html_safe end end

自定义错误消息,它适用于注册和密码页面,但不适用于会话页面。 为什么是这样? 我知道我可以添加这样的东西:

  
'close' %>
'close' %>

我的application.html.erb文件和错误消息将显示在那里,但我不明白为什么我必须添加,当我已经有设计帮助器。 对于密码和注册,我只需要添加但是会话页面似乎没有这种方式。 我不确定这是否如何设计或者是否有我遗漏的东西。

编辑:我生成了会话控制器,但自从生成它以来我从未改变过任何内容。 根据我的理解,设计将只使用其默认控制器,直到我更改我生成的那个。 我的密码控制器也是这样的。 我确实对注册控制器进行了一些更改,以配置允许的参数。

 class Users::SessionsController < Devise::SessionsController end 

具有空白/错误字段的登录不会触发(您的)模型上的validation ,因此不会显示validation错误!

如果您使用byebug调试(例如在视图的第一行),您会注意到

 resource.errors.count # => 0 flash # => ....@flashes={"alert"=>"Invalid email or password."} 

设计使用特定登录错误消息填充“警报闪存”,该错误消息对于此登录环境是唯一的。

为什么没有看到所有模型validation错误消息? 因为这没有意义:假设您的模型具有强制:gender属性,其中包含validates_presence_of :gender 。 如果添加了正常的模型错误,那么当您的用户尝试使用错误的登录信息登录时,您还会在错误列表中看到“性别不能为空”:oops:。

devise_error_messages! 是一种特定的设计方法,旨在显示那些特定的错误。 您可以将其视为用于登录的字段的部分validation(并且在您的设计配置文件中定义)

解决方法:

如果您确实要显示所有错误消息,则可以明确地运行validation:

devise_error_messages!的开头devise_error_messages!

 resource.validate # It will generate errors and populate `resource.errors` 

我相信它不应该搞乱已经运作良好的其他行动(注册等)

对于较新版本的Rails / Devise,我建议:

而不是<%= devise_error_messages! %> <%= devise_error_messages! %>做:

  <% if flash[:alert] %> <%= flash[:alert] %> <% end %> 

您的测试可能看起来像这样(注意,您必须将其作为’function’function测试才能访问“页面”变量):

 RSpec.feature 'Sign In', :type => :feature do describe "correct error message w/ wrong password" do before :each do @user = create(:user) @user.confirm visit new_user_session_path fill_in "user_email", with: @user.email fill_in "user_password", with: "wrongpassword" click_button "Log in" end it "tells user on page 'Invalid Email or password'" do expect(page).to have_text("Invalid Email or password") end end end 

当你运行devise:install (或类似的东西)时,它必须创建带有一些特定代码行的视图来显示这些消息。

如果您查看此链接 ,他们会解释您可以添加<%= devise_error_messages! %> <%= devise_error_messages! %>在您的视图中显示这些错误消息(这与HTML中某处的通用<% flash.each {...} %>没有什么不同…)

最有可能的是,与会话相关的视图不包含此行代码。

我喜欢这种方式。 HTML部分虽然是原创的。

我不想分开显示有关身份validation的错误消息。 所以,我正在使用这种方式。

 module DeviseHelper def devise_error_messages! flash_alerts = [] if !flash.empty? flash_alerts.push(flash[:error]) if flash[:error] flash_alerts.push(flash[:alert]) if flash[:alert] flash_alerts.push(flash[:notice]) if flash[:notice] sentence = I18n.t("devise.failure.invalid") #=> "Invalid email or password." else sentence = I18n.t("errors.messages.not_saved", count: resource.errors.count, resource: resource.class.model_name.human.downcase) end return "" if resource.errors.empty? && flash_alerts.empty? errors = resource.errors.empty? ? flash_alerts : resource.errors.full_messages messages = errors.map { |msg| content_tag(:li, msg) }.join html = <<-HTML 
#{sentence}
    #{messages}
HTML html.html_safe end end