2017-04-09 18 views
0

Michael HartlのRuby on Railsチュートリアルの本を読んで、自分のアプリケーションにユーザーを追加しようとしました。第6章を読んで、自分のユーザにとって必要と思われるもの、特にパスワードとパスワードの確認を「has_secure_password」で追加しました。Rails - 不明な属性のパスワード

ユーザーモデルに「has_secure_password」を追加すると、「password_digest」をモデルに追加すると「password」と「password_confirmation」という属性が追加されると考えました。私はその本が私に指示したようにそれをしました。私は、テストを実行したときしかし、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 'bcrypt-ruby', :require => 'bcrypt'

私はRailsの5を使用していますが、それは「has_secure_password」のように思える:私は「宝石bcryptのインストール」を使用して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クラス内にUserクラスがありますか? passwordとpassword_confirmationのattr_accessorを宣言したのはなぜですか? –

答えて

0

更新:

私はこれをテストして、それが動作します。だから希望もあなたのために働くでしょう:) MiniTestがBCryptでうまく動作しないように見えます。私は同じエラーを受け取った - 未定義のパスワードが、後で私の変更を実装し、さらにうまくいった。


オリジナルの答え: - ゲッター特にセッター:password:password_confirmationためメソッドを追加し、あなたのsolution設立のよう

は、それは私が、これは何のローミングサービスを行っていないことを考えさせられました。 has_secure_passwordは、実質的にBCryptを実行するものを作成するためです。だから、それは暗号化/暗号化の周りに行くのではないのですか?もしそうなら、それは安全ではありません。だから、テストのために残されたオプションだけが、BYcriptをテストスイートに持っていくのが分かります。ユーザーテストでは

:私はこのような何かが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フォームを削除してUserモデルを作成してください。

p.s. Userクラスのコードスニペットを修正してください。または、実際にこのように2回定義されていますか?:

class User < ApplicationRecord 

    has_many :activities 

    class User < ActiveRecord::Base 
+1

ありがとうございました。これはうまくいき、ユーザーの2つの定義に関する助言に感謝します。私はこれでもまだまだ新しいので、おそらく別の問題を修正しようとしたが、削除するのを忘れてしまった解決策でした。 – VectorConvoy

関連する問題