Rails 中的验证冲突

Validations conflicts in Rails

我正在做一个项目,我遇到了一个我试图解决但没有进展的问题。

所有这些都是在我开始实现 Forgot Password 重置密码功能时发生的。我有一个 User Model,它验证了 passwordpassword_confirmation。我使用这些进行注册并且工作正常。

但是对于此功能,我使用了一个名为 PasswordResets 的新控制器。我正在为我的用户 table 生成一个名为 password_reset_token 的字符串。还有password_reset_sent_at记录了用户要求重置的时间。过程是这样的;

1) The User clicks Forgot Password?

2) He is redirected to a page where he is asked to enter his email.

3) Controller checks if the email is present in database, if yes then ;
3.1) I generate a random password_token by using SecureRandom and also time when he started the request.
3.2) Now the save happens here for sending the mail to user. Here the problem occurs. The password_reset_token is not getting saved into table.

其背后的原因是我在 User.rb 中使用 passwordpassword _confirmation 的验证。这里发生的动作是 :update,因此在更新记录时要求 passwordpassword_confirmationpassword_reset_token 和时间一起发送。

但我尝试通过将验证保持为 :on => :create 来解决,现在它运行良好,但是当我使用 link 重置时,我的验证将不适用于 passwordpassword_confirmation。这对我来说就像一个僵局。我知道这有点令人困惑,我正在粘贴一些代码来理解问题。

我的 PasswordResets Controller 创建操作:

  def create
    user= User.find_by_email(params[:email])
    if user
      user.send_password_reset
      UserMailer.password_reset(self).deliver
      flash[:success] = "Email sent with password reset instructions."
      redirect_to root_url
    else
      flash[:error] = "Email doesn't exit."
      render 'password_resets/new'
    end
  end

我的 User Model (user.rb)

class User < ActiveRecord::Base

  has_secure_password

  EMAIL_REGEX = /\A[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}\Z/i


  validates_confirmation_of :password_confirmation

  validates :username, :presence => true,
                       :uniqueness => true,
                       :length => {:within => 8..25}
  validates :email, :presence => true,
                    :uniqueness => true,
                    :format => EMAIL_REGEX

  validates :password, :length => {:within => 8..25}

  validates :password_confirmation, :presence => true

  def send_password_reset
    generate_token(:password_reset_token)
    self.password_reset_sent_at = Time.zone.now
    save!
    UserMailer.password_reset(self).deliver
  end


  def generate_token(column)
    begin
      self[column] = SecureRandom.urlsafe_base64
    end while User.exists?(column => self[column])
  end


end

错误显示在 send_password_reset 中的 save! 处。我附上一张图片。

我知道这个问题可以通过使用 :on=>:create 进行验证来解决,因为 :update 请求正在发生。但是当我在我的控制台中得到确认 link 并使用它时,密码验证和 password_confirmation 不起作用,因为这里的操作是 :update。这就像一个僵局。

我真的很感谢任何帮助我走出迷宫的人。

谢谢。

您可以使用以下示例跳过验证。

def send_password_reset
  generate_token(:password_reset_token) 
  self.password_reset_sent_at = Time.zone.now
  self.save(validate: false)
  UserMailer.password_reset(self).deliver
end