我一直在关注Michael Hartl的Ruby on Rails教程书,试图将用户添加到我的应用程序中。阅读第6章,我添加了我认为是我的用户的必要字段,特别是密码和密码确认通过" has_secure_password"。
我认为添加" has_secure_password"我的用户模型将包含属性"密码"和" password_confirmation"如果我添加一个" password_digest"到模型。正如书中指示的那样,我已经这样做了。但是,当我运行测试时,Rails会给我以下错误:
Error:
UserTest#test_should_be_valid:
ActiveModel::UnknownAttributeError: unknown attribute 'password' for User.
test/models/user_test.rb:8:in `setup'
我尝试了this解决方案,它仍然给了我同样的错误,没有识别属性"密码"或" password_confirmation"。我使用" gem install bcrypt"安装了bcrypt。并在我的gem文件中包含以下内容:
gem' bcrypt-ruby',:require => ' bcrypt'
我正在使用Rails 5,它似乎" has_secure_password"没有提供我需要的密码属性。任何人都可以看到我错过了什么或做错了导致" has_secure_password"不按预期工作?感谢
用户模型:
class User < ApplicationRecord
has_many :activities
class User < ActiveRecord::Base
attr_accessor :name, :email, :password, :password_confirmation
has_secure_password
validates :first_name, presence: true, length: {minimum: 1}
validates :last_name, presence: true, length: {minimum: 1}
validates :email, presence: true, uniqueness: true, length: {minimum: 5}
validates :username, presence: true, uniqueness: true, length: {minimum: 1}
validates :password_digest, length: {minimum: 6}
validates :password, :confirmation => true, length: {minimum: 4}
validates :password_confirmation, presence: true
#-----------------------New Stuff ---------------------------------------
acts_as_authentic do |c|
c.crypto_provider = Authlogic::CryptoProviders::Sha512
end
#------------------------------------------------------------------------
#---------------Unsure if working--------------
#validates_presence_of :password, :on => :create
#validates_presence_of :email
#validates_uniqueness_of :email
#----------------------------------------------
def self.authenticate(email, password)
user = find_by_email(email)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
def encrypt_password
if password.present?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
end
end
为模型中的混乱代码道歉,因为我还在学习Rails。
用户控制器:
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
flash[:success] = 'Account created'
else
flash[:notice] ='ERROR: Account was not created'
redirect_to 'users/new'
end
end
def show
@user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
end
用户表:
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "username"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "persistence_token"
t.string "password_digest"
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
end
用户测试:
require 'test_helper'
class UserTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
def setup
@user = User.new(first_name: 'test', last_name: 'tester', password: '1234',email: 'test1@mail.com',
password: 'foobar', password_confirmation: 'foobar')
end
test 'should be valid' do
assert @user.valid?
end
end
答案 0 :(得分:0)
更新:
我已经测试了这个并且它有效。所以希望对你也有用:)看起来MiniTest与BCrypt不兼容。我收到了同样的错误 - 未定义的密码,但后来实现了我的更改,它进展得更顺利。
原始答案:
从你创立的solution开始,它让我觉得这没有任何意义 - 为:password
和{添加 getter ,特别是 setter 方法{1}}。因为:password_confirmation
创建了那些通过BCrypt运行的虚拟。所以它不是围绕加密/加密吗?如果是这样,那就不安全了。所以只留下测试选项我看到将BYcript带入测试套件。我认为像这样的东西可以做trck:
在用户测试中:
has_secure_password
请注意,我删除了重复的require 'bcrypt'
def setup
@user = User.new(first_name: 'test', last_name: 'tester', password: BCrypt::Password.create("my password") ,email: 'test1@mail.com', password_confirmation: 'my password')
end
test 'should be valid' do
assert @user.valid?
end
。由于您正在测试用户是否的特定测试,因此不应传递不同的密码甚至是重复的属性...为此进行另一次测试(也是结帐灯具,它们非常适用于创建测试对象,以及更复杂案例的工厂。)
当然,从您的用户模型中删除password: 'foobar
表单。
P.S。并请修复User类的代码片段。或者它是否真的定义了两次?:
atr_accessor :password, :password_confirmation