2017-04-09 64 views
0

我一直在关注Michael Hartl的Ruby on Rails教程,尝试将用户添加到我的应用程序中。阅读第6章,我已经添加了我认为是我的用户必需的字段,特别是通过“has_secure_password”确认密码和密码确认。Rails - 未知的属性密码

我认为向我的用户模型添加“has_secure_password”将包括属性“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”。我安装bcrypt使用“宝石安装bcrypt”,并列入我的宝石文件中的以下内容:

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: '[email protected]', 
        password: 'foobar', password_confirmation: 'foobar') 
    end 
    test 'should be valid' do 
    assert @user.valid? 
    end 
end 
+0

为什么你在User类中有一个User类?你为什么要声明一个attr_accessor来输入密码和password_confirmation? –

回答

0

更新:

我已经测试了这一点,它的工作原理。所以希望也会对你有用:)看起来MiniTest不适合BCrypt。我收到了同样的错误 - 未定义的密码,但稍后实施了我的更改并进一步完善。


原来的答复:

当你的创办solution它让我觉得,这是没有SENCE - 添加吸气尤其是二传手方法:password:password_confirmation。因为has_secure_password创建那些实际上通过BCrypt运行。那么它不是围绕着加密/加密吗?如果是这样就不安全。所以只有选择留下来进行测试,我会将脚本带入测试套件。我觉得这样的事情可能会做的TRCK:

在用户测试:

require 'bcrypt' 

    def setup 
    @user = User.new(first_name: 'test', last_name: 'tester', password: BCrypt::Password.create("my password") ,email: '[email protected]', password_confirmation: 'my password') 
    end 
    test 'should be valid' do 
    assert @user.valid? 
    end 

注意,我删除重复password: 'foobar。由于使用该特定测试,您正在测试用户是否可以创建,因此不应传递不同的密码或重复的属性...对此进行另一项测试(还包括检查装置,它们非常适合创建测试对象,以及用于更复杂情况的工厂)。

当然,请从您的用户模型中删除atr_accessor :password, :password_confirmation

p.s.并请修复您的User class代码片段。或者它是这样定义两次吗?:

class User < ApplicationRecord 

    has_many :activities 

    class User < ActiveRecord::Base 
+1

谢谢你的帮助。这工作,并感谢您对用户的两个定义的建议。我在这方面还有点新意,所以这可能是我尝试解决另一个问题但忘记删除它的解决方案。 – VectorConvoy