2013-07-30 8 views
6

レール付き4 has_secure_passwordを私のユーザモデルに使用すると、設定しなければ:password_confirmationは実行されませんが、テストを実行するとエラーが発生します:パスワードの確認は、次のように空白にすることはできません。レール4 has_secure_passwordレンダリングパスワードの確認オプション

Failures: 

1) User 
Failure/Error: it { should be_valid } 
    expected #<User id: nil, name: "joe", email: "[email protected]", created_at: nil, 
    updated_at: nil, password_digest: "$2a$04$mcRr/msgYQR3kBVc3kv/m.UotBJuJuSXZKMw 
    /eHTvU87..."> to be valid, but got errors: Password confirmation can't be blank 

私のテストファイルは以下のようになります。

require 'spec_helper' 

describe User do 

    before { @user = User.new(name: 'joe', email: '[email protected]', password: 'foo') } 

    subject { @user } 
    #.... 
    #.... 
    describe "when password is not present" do 
    before { @user.password = "" } 
    it { should_not be_valid } 
    end 
end 

私はこのエラーを取得する理由としては、そこにありますそれのためのolution?これに感謝の

答えて

5

変更テストのbeforeライン:それを修正する必要があり

before { @user = User.new(
    name: 'joe', 
    email: '[email protected]', 
    password: 'foo', 
    password_confirmation: 'foo') #<== this line! 
} 

これが何であるかについて:

あなたは、あなたはかなり任意のウェブサイト上で新しいアカウントを作成するとき、彼らはパスワードを構成し、2回入力するように依頼する方法を知っていますか?それがこれです。新しいユーザーを作成すると、has_secure_passwordはパスワードを2回入力して誤字を犯さないようにします。

password!= password_confirmationの場合、例外がスローされ、ユーザーは作成されません。

この場合も、これはユーザーの作成でのみ使用されます。ログインフォームに2つのパスワードを入力する必要はありません。 このフィールドをモデルまたはDBに追加する必要はありません。

ユーザ作成フォームをお持ちで、password_confirmationフィールドを使用したくない場合は、そうする必要はありません。セーブなどを呼び出す前に、コントローラーにpassword_confirmation = passwordを設定することができます。

しかし、ユーザー作成ため、password_confirmation必須では存在して

+0

が、私は私のアプリにpassword_confirmationを追加しないと、私は – medBo

+0

一度だけパスワードが必要ですこれは、ユーザー作成時にのみ使用されます。それをモデルに追加する必要はありません。これは 'has_secure_password'の機能です。 –

+0

私は理解していませんより多くを説明してください! (私の形式では、私はパスワードのためのフィールドを正当化し、パスワードの確認のためのフィールドはもうないでしょう) – medBo

21

かいつまん

has_secure_password validations: false # This is the key to the solution 
validates :password, presence: true, length: { minimum: 6 } # Or an length you want 

長い話

  1. docsthe source code言う:

    使用すると、確認の検証を必要としない場合password_confirmation属性に値を設定しないと、検証は実行されません。

  2. しかし、彼らはまた言う:作成上のパスワードの存在を

    検証、パスワード の確認(+のpassword_confirmation +属性を使用して)自動的に追加されます。 検証を無効にする場合は、バリデーションをfalse: 引数として渡します。必要であれば、手作業でより多くの検証を追加することができます。

  3. 項目#1は完全な説明ではありません。すべての検証 をオフにして、この作業をポイント2で説明したようにするための独自の検証ルールを追加する必要があります。

私はこれをいつか過ごし、教訓を得ました:あなたが混乱しているときにソースコードを見つけてください。これは苦しいやり方ですが、いつか正しい方法です。

+0

存在:trueは検証として機能しません。falseは存在条件を削除します。しかし、最小の長さが6であるので、重要ではない – shailesh

+1

Rails 4は、パラメータとして送信しないと確認を完全に無視するので、 'password_confirmation'属性をホワイトリストに登録するのを忘れた場合、無視され、検証が勝ちますものを言う。これを慎重に! –

+0

@shailesh 'validations:false'は、' has_secure_password'によって追加されたデフォルトのバリデーションだけを削除します。パスワードフィールドに 'presence:true'のようなカスタムバリデーションを追加することは、意図した通りに機能します。 – mltsy

1

私はRailsの4.0.13から4.1へと越えて、このアプリを取得するまで、私は一時的な措置としてこれをしなかった:

class User < ActiveRecord::Base 
    has_secure_password 
    # Tempfix until Rails 4.1 https://github.com/rails/rails/pull/11107#issuecomment-21850919 
    raise "Get rid of this on Rails 4.1+" if Rails::VERSION::STRING != "4.0.13" 
    before_validation { self.password_confirmation ||= password } 
end 
+0

これは正確に何をするのですか?それは検証を削除するのでしょうか、パスワードの確認をパスワードと同じですか? –

+1

@SurgePedroza後者です。確認がnilの場合、検証が実行される前にパスワード値が割り当てられます。 –

関連する問題