我正在尝试将忘记密码字段与登录页面放在一起,但如果用户未注册(而不是在应用程序数据库中),则会重定向到原始设备忘记密码页面并显示错误(http:// localhost:3000 /用户/密码).如何使错误显示在与登录页面相同的页面中(http:// localhost:3000 / users / sign_in)?
在app / views / devise / sessions / new.html.erb文件中
<%= simple_form_for(resource,as: resource_name,url: session_path(resource_name)) do |f| %> <%= f.email_field :email,required: false,autofocus: true,placeholder: "Username" %> <%= f.password_field :password,placeholder: "Password" %> <%= f.button :submit,"Sign In",class: "btn btn-success btn-sm" %> <div class="remember-forgot"> <div class="row"> <div class="col-md-6"> <%= f.input :remember_me,as: :boolean if devise_mapping.rememberable? %> </div> <div class="col-md-6 forgot-pass-content"> <a href="javascription:void(0)" class="forgot-pass">Forgot Password</a> </div> </div> </div> <% end %> <!-- where reset is --> <div class="pass-reset"> <%= simple_form_for(resource,url: password_path(resource_name),namespace: 'forgot',html: { method: :post }) do |f| %> <%= f.error_notification %> <label>Enter the email you signed up with</label> <%= f.email_field :email,required: true,placeholder: "Email" %> <%= f.submit "Submit",class: "pass-reset-submit btn btn-success btn-sm" %> <% end %> </div>
解决方法
显然,具有相同字段的同一对象的两个表单不应该是一个页面,一个应该保留在新页面中.但我仍然尝试过你的问题,并且需要做一些事情
1)我必须在用户范围内覆盖设计的密码控制器.
class Users::PasswordsController < Devise::PasswordsController # GET /resource/password/new def new super end # POST /resource/password def create self.resource = resource_class.send_reset_password_instructions(resource_params) if successfully_sent?(resource) flash[:notice] = "sent password" redirect_to :root else render "devise/sessions/new" end end # GET /resource/password/edit?reset_password_token=abcdef def edit super end # PUT /resource/password def update super end protected def after_resetting_password_path_for(resource) super(resource) end # The path used after sending reset password instructions def after_sending_reset_password_instructions_path_for(resource_name) super(resource_name) end end
然后我的设计/会话/新页面将如下所示(你可以添加显示表单的逻辑,只有当他点击他忘记密码按钮时.这应该很简单.只需添加隐藏类,然后单击删除隐藏类.)
<%= form_for(resource,url: session_path(resource_name)) do |f| %> <div class="field"> <%= f.label :email %><br /> <%= f.email_field :email,autofocus: true %> </div> <div class="field"> <%= f.label :password %><br /> <%= f.password_field :password,autocomplete: "off" %> </div> <% if devise_mapping.rememberable? -%> <div class="field"> <%= f.check_Box :remember_me %> <%= f.label :remember_me %> </div> <% end -%> <div class="actions"> <%= f.submit "Log in" %> </div> <% end %>
#assuming devise_mapping是否可以恢复?选项.如果条件允许,您也可以保留以下表格
<h2>Forgot your password?</h2> <%= form_for(resource,namespace: "forget",html: { method: :post }) do |f| %> <%= devise_error_messages! %> <div class="field"> <%= f.label :email %><br /> <%= f.email_field :email,autofocus: true %> </div> <div class="actions"> <%= f.submit "Send me reset password instructions" %> </div> <% end %>
需要告诉路由使用我的密码控制器.
devise_for :users,controllers: { passwords: 'users/passwords' }
这些东西将导致在用户登录表单下显示错误,但路径将保持为http://localhost:3000/users/password.为什么,因为我们正在渲染页面而不是重定向.渲染只显示视图而无需进入控制器操作.现在,即使有人尝试以某种方式将错误消息发送到会话控制器(在覆盖该控制器之后),就像这样
redirect_to new_user_session_path,:messages => resource.errors
仍然没有帮助,为什么因为在session #new中我们正在重新初始化资源,因为它是新的动作,所有错误都将消失.
我不确定这是否令您满意,或者这是否符合您的要求.我试图掩盖所有事情.如果一些可靠的或官方的消息来源能提供更好的回应,我会很高兴的.这肯定会增加我的知识.