2017-04-09 63 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