RoR:忘记密码并登录 - 在同一页面

RoR: Forgot Password & Sign In - in same page

我正在尝试将忘记密码字段与登录页面放在一起,但是如果用户未注册(并且不在应用程序数据库中),则它会重定向到原始设计的忘记密码页面并出现错误(http://localhost:3000/users/password).如何使错误出现在登录页面 (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, required: false, 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, as: resource_name, 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, autofocus: true, placeholder: "Email" %>
    <%= f.submit "Submit", class: "pass-reset-submit btn btn-success btn-sm" %>
  <% end %> 
</div>

所以有一个 javascript link 如果用户忘记了他们的登录凭据,输入字段将显示在其中。

显然,具有相同字段的同一对象的两个表单不应该在一页上,一个应该留在新页面上。但我仍然尝试过你的问题,需要做以下事情

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

然后我的 devise/sessions/new 页面将如下所示(您可以添加仅当单击忘记密码按钮时才显示表单的逻辑。这应该很简单。只需添加隐藏 class 和 on单击删除隐藏 class。)

登录

<%= form_for(resource, as: resource_name, 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 %>

#假设 devise_mapping 可以恢复?选项。您还可以在 if 条件

中保留以下表格
<h2>Forgot your password?</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), 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。为什么因为我们正在渲染页面而不是重定向。 render 只显示视图而不去控制器操作。现在即使有人试图以某种方式(也覆盖该控制器之后)将错误消息发送到会话控制器,就像这样

    redirect_to new_user_session_path, :messages => resource.errors

这仍然无济于事,因为在 session#new 中我们正在重新初始化资源,因为它是新操作,所有错误都将消失。

我不确定这是否令您满意,或者这是否不符合您的要求。我试图涵盖所有的事情。如果一些可靠的或官方的消息来源能提供更好的回应,我会很高兴。那肯定也会增加我的知识。