2017-04-09 2 views
0

나는 Michael Hartl의 Ruby on Rails 튜토리얼 서적을 따라 내 애플리케이션에 사용자를 추가하려고합니다. 6 장을 읽으면 "has_secure_password"를 통해 암호와 암호 확인과 같은 사용자 필드에 필요한 정보를 추가했습니다.레일즈 - 알 수없는 속성 비밀번호

내 사용자 모델에 "has_secure_password"를 추가하면 "password_digest"를 모델에 추가하면 "password"및 "password_confirmation"속성이 포함될 것이라고 생각했습니다. 그 책이 나에게 지시 한대로 나는 그것을했다. 내가 테스트를 실행할 때, 레일은 나에게 다음과 같은 오류를 제공합니다 :

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 설치하고 내 보석 파일에 다음을 포함 : 나는 레일 (5)를 사용하고와 "has_secure_password"암호를 제공하지 않는 것은 내가 필요 속성처럼 보인다

gem 'bcrypt-ruby', :require => 'bcrypt'

합니다. 아무도 내가 놓친 것을 볼 수 있거나 "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 

사과 나는 아직도 레일을 배우고있다.

사용자 컨트롤러 :

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 클래스가있는 이유는 무엇입니까? 왜 당신은 password와 password_confirmation을위한 attr_accessor를 선언 했습니까? –

답변

0

업데이트 :

나는이를 테스트 한 작동합니다. 그래서 희망도 당신을 위해 일할 것입니다 :) Mini Test가 BCrypt와 잘 작동하지 않는 것처럼 보입니다. 나는 정의되지 않은 패스워드를 받았다. 그러나 나중에 나의 변화를 구현했고 더 잘 진행되었다.


원래 답 : - 게터 특히 세터 :password:password_confirmation에 대한 방법을 추가하여 solution 설립의로

는 날이 더 sence하지 않는다라고 생각했다. has_secure_password은 BCrypt를 통해 실행되는 가상 서버를 가상으로 만듭니다. 그렇다면 암호 화/암호화가 아닌가? 그렇다면 안전하지 않습니다. 그래서 테스트 용으로 남아있는 옵션은 BYcript를 테스트 스위트에 넣는 것입니다. 사용자 테스트에서

: 나는 password: 'foobar 중복 제거

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 

주 나는 이런 일이 TRCK을 할 것 같아요. 이 특정 테스트를 통해 사용자 을 만들 수 있는지 테스트 중이므로 다른 암호 또는 중복 된 특성을 전달해서는 안됩니다 ...이것에 대한 또 다른 테스트를해라. (체크 아웃 픽스처도있다. 테스트 객체를 생성하는 데는 유용 할뿐만 아니라 복잡한 경우를위한 팩토리도있다.)

물론 사용자 모델 atr_accessor :password, :password_confirmation을 제거하십시오.

p.s. User 클래스에 대한 코드 스 니펫을 수정하십시오. 또는 실제로 이렇게 두 번 정의 되었습니까? :

class User < ApplicationRecord 

    has_many :activities 

    class User < ActiveRecord::Base 
+1

도움 주셔서 감사합니다. 이는 사용자의 두 가지 정의에 대한 조언을 얻고 협조 해 주셔서 감사합니다. 나는 여전히 다소 새로운 것이므로 아마 다른 문제를 해결하려했지만 그것을 제거하는 것을 잊어 버린 해결책 일 것입니다. – VectorConvoy