如何跳过has_secure_password验证

时间:2012-05-04 03:52:13

标签: ruby-on-rails ruby ruby-on-rails-3 validation

在我的应用中,只有管理员可以创建新的用户记录。用户通过电子邮件发送激活链接,并在其中设置密码。

我想使用has_secure_passord方法(railscast):

class User < ActiveRecord::Base
  has_secure_password
  ...
end

效果很好,但它会自动验证密码摘要的存在...所以当管理员创建记录时,验证失败。我有办法跳过自动添加的password_digest验证而不跳过我添加的其他人吗?

3 个答案:

答案 0 :(得分:30)

由于4.X版本的rails,has_secure_password采用了一个选项:验证。如果将其设置为false,则不会运行验证。

3.X版本的gem不支持此参数。但是,您可以从支持此参数的latest 4.0.XRC code反向移植activemodel / lib / active_model / secure_password.rb。

因此,您的代码将如下所示:

class User < ActiveRecord::Base
  has_secure_password :validations => false
  ...
end

答案 1 :(得分:11)

我决定自己做自定义身份验证。以下解决方案将验证密码,但仅在设置密码时验证密码。这允许管理员在不添加密码的情况下创建用户。

class User < ActiveRecord::Base
  include BCrypt

  attr_accessor :password, :password_confirmation

  validates :password, length: (6..32), confirmation: true, if: :setting_password?

  def password=(password)
    @password = password
    self.password_hash = Password.create(password)
  end

  def authenticate(password)
    password.present? && password_hash.present? && Password.new(password_hash) == password
  end

private

  def setting_password?
    password || password_confirmation
  end

end

如果有人发布了允许我仍使用has_secure_password方法的答案,我会接受。

答案 2 :(得分:1)

没有办法跳过验证,但编写自己的方法版本很容易,它允许您传递参数以确定是否验证password_digest字段的存在。

只需像SecurePassword module(通过ActiveModel)那样延长ActiveSupport::Concern并添加您自己的安全密码方法。

module ActiveModel
  module MySecurePassword
    extend ActiveSupport::Concern

    module ClassMethods
      def my_has_secure_password(validate_password_digest=true)
        # you custom logic
      end
    end
  end
end