在功能规范中使用带有 has_secure_password 的 FactoryGirl 时出错
Error using FactoryGirl with has_secure_password in feature spec
如果相关,也使用 mongoid。
当我用factory girl创建用户时,它说用户是有效的。但是,当我通过 ActiveRecord 访问该用户时,却说它无效。以下是问题的概述:
user = create(:user, :activated)
user.valid? # => true
User.count # => 1
db_user = User.first
db_user == user # => true
db_user.valid? # => false
db_user.errors.count # => 0
# it only shows the error messages once I try to modify an attribute
db_user.email = "user@example.com"
db_user.save # => false
db_user.errors # => @messages={:password=>["is too short (minimum is 6 characters)", "can't be blank"]}
这是我的工厂:
FactoryGirl.define do
factory :user do
name { Faker::Name.name }
email { "#{name.gsub(/[^0-9a-zA-Z]/i, '')}@example.com" }
phone { Faker::Base.numerify("#{"#" * 10}") }
admin false
password "password"
password_confirmation "password"
end
end
这是用户模型的相关部分:
class User
include Mongoid::Document
include ActiveModel::SecurePassword
field :name, type: String
field :email, type: String
validates :password, length: { minimum: 6 },
presence: true
has_secure_password
您总是运行进行额外的验证。 has_secure_password
已经检查 password。所以你不需要存在验证。
您可以简单地使您的验证有条件
validates :password, length: { minimum: 6 }, if: Proc.new{|u| u.password_changed? }
我认为使用 ActiveModel::Dirty
应该可行
如果没有,您可以运行验证是否存在。
validates :password, length: { minimum: 6 }, if: Proc.new{|u| u.password.present? }
我决定看一下 Michael Hartl 的 "Rails Tutorial - Adding a secure password" 部分。看到他在has_secure_password
之前写的代码是validates
,如下图:
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
尝试更改顺序,看看是否可行。我已经对它进行了测试,但这是我刚开始时使用的主要资源之一,过去它对我有用。祝你好运。
了解 has_secure_password
的内部工作原理很重要:
创建用户或更改其密码时,必须设置其 password
(以及 – 根据配置 – password_confirmation
)属性。但在内部 password
字段是 而不是 存储在数据库中,但它的值被散列并存储在名为 password_digest
.
的数据库字段中
这意味着:当您从数据库加载现有用户时,其 password
属性将为 nil
(但 password_digest
应该仍然存在)。因此,当您检查此类用户是否存在 password
.
时,它将无效
为避免此问题,仅在创建新用户时验证密码是否存在,或者如果用户的 password
不是空白,这意味着用户尝试更新其密码:
# there must be a password on create
validates :password, presence: true, on: :create
# the password must follow conventions when present (of example on update)
validates :password, length: { minimum: 6 }, allow_blank: true
如果相关,也使用 mongoid。
当我用factory girl创建用户时,它说用户是有效的。但是,当我通过 ActiveRecord 访问该用户时,却说它无效。以下是问题的概述:
user = create(:user, :activated)
user.valid? # => true
User.count # => 1
db_user = User.first
db_user == user # => true
db_user.valid? # => false
db_user.errors.count # => 0
# it only shows the error messages once I try to modify an attribute
db_user.email = "user@example.com"
db_user.save # => false
db_user.errors # => @messages={:password=>["is too short (minimum is 6 characters)", "can't be blank"]}
这是我的工厂:
FactoryGirl.define do
factory :user do
name { Faker::Name.name }
email { "#{name.gsub(/[^0-9a-zA-Z]/i, '')}@example.com" }
phone { Faker::Base.numerify("#{"#" * 10}") }
admin false
password "password"
password_confirmation "password"
end
end
这是用户模型的相关部分:
class User
include Mongoid::Document
include ActiveModel::SecurePassword
field :name, type: String
field :email, type: String
validates :password, length: { minimum: 6 },
presence: true
has_secure_password
您总是运行进行额外的验证。 has_secure_password
已经检查 password。所以你不需要存在验证。
您可以简单地使您的验证有条件
validates :password, length: { minimum: 6 }, if: Proc.new{|u| u.password_changed? }
我认为使用 ActiveModel::Dirty
应该可行如果没有,您可以运行验证是否存在。
validates :password, length: { minimum: 6 }, if: Proc.new{|u| u.password.present? }
我决定看一下 Michael Hartl 的 "Rails Tutorial - Adding a secure password" 部分。看到他在has_secure_password
之前写的代码是validates
,如下图:
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
尝试更改顺序,看看是否可行。我已经对它进行了测试,但这是我刚开始时使用的主要资源之一,过去它对我有用。祝你好运。
了解 has_secure_password
的内部工作原理很重要:
创建用户或更改其密码时,必须设置其 password
(以及 – 根据配置 – password_confirmation
)属性。但在内部 password
字段是 而不是 存储在数据库中,但它的值被散列并存储在名为 password_digest
.
这意味着:当您从数据库加载现有用户时,其 password
属性将为 nil
(但 password_digest
应该仍然存在)。因此,当您检查此类用户是否存在 password
.
为避免此问题,仅在创建新用户时验证密码是否存在,或者如果用户的 password
不是空白,这意味着用户尝试更新其密码:
# there must be a password on create
validates :password, presence: true, on: :create
# the password must follow conventions when present (of example on update)
validates :password, length: { minimum: 6 }, allow_blank: true