8290


Rils tutorial 6章で躓いており、教えていただきたいです。

6.26にhas_secure_passwordを追加すればテストがパスするようにあると書いて有りますが、パスしません。

[code]

    Failures:
    
    1) User when password is not present 
         Failure/Error: it { should_not be_valid }
           expected #<User id: nil, name: "Example User", email: "user@example.com", created_at: nil, updated_at:     nil, password_digest: "$2a$04$P8/lQ.ytJHrnRbPM..Z4qeUAIipdMNjbOtohvnJI/31..."> not to be valid
         # ./spec/models/user_spec.rb:69:in `block (3 levels) in <top (required)>'
    
    Finished in 0.36208 seconds
    25 examples, 1 failure
    
    Failed examples:
    
    rspec ./spec/models/user_spec.rb:69 # User when password is not present 
    
    Randomized with seed 52215
    
[/code]

このテストを逆にshoud be_validにすれば通ります。こういうものでしょうか？

参考までに使用したテストの全文です。

[code]

    require 'spec_helper'
    
    describe User do
    
        before do
            @user = User.new(name: "Example User", email: "user@example.com",
                password: "foobar", password_confirmation: "foobar")
        end
    
        subject { @user }
    
        it { should respond_to(:name) }
        it { should respond_to(:email) }
        it { should respond_to(:password_digest) }
        it { should respond_to(:password) }
        it { should respond_to(:password_confirmation) }
    
        it { should be_valid }
    
        describe "when name is not present" do
            before { @user.name = " " }
            it { should_not be_valid }
        end
    
        describe "when email is not present" do
            before { @user.email = " " }
            it { should_not be_valid }
        end
    
        describe "when name is too long" do
            before { @user.name = "a" * 51 }
            it { should_not be_valid }
        end
    
        describe "when email format is invalid" do
            it "should be invalid" do
                addresses = %w[user@foo,com user_at_foo.org example.user@foo.foo@bar_baz.com foo@bar+baz.com]
                addresses.each do |invalid_address|
                    @user.email = invalid_address
                    expect(@user).not_to be_valid
                end
            end
        end
    
        describe "when email format is valid" do
            it "should be valid" do
                addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
                addresses.each do |valid_address|
                    @user.email = valid_address
                    expect(@user).to be_valid
                end
            end
        end
    
        describe "when email address is already taken" do
            before do
                user_with_same_email = @user.dup
                user_with_same_email.email = @user.email.upcase
                user_with_same_email.save
            end
            it { should_not be_valid }
        end
    
        describe "when password is not present" do
            before do
                @user = User.new(name: "Example User", email: "user@example.com",
                    password: " ", password_confirmation: " ")
            end
            it { should_not be_valid }
        end
    
        describe "when password doesn't match confirmation" do
            before { @user.password_confirmation = "mismatch" }
            it { should_not be_valid }
        end
    end
    
[/code]


CC BY-SA 3.0
2015-03-23T12:05:50.963
8270
2015-03-24T05:31:44.937
8967
question
ruby ruby-on-rails
Rails tutorial chapter6 has_secure_passwordの動作が解説と一致しない


User側の実装も見てみないと何とも言えませんが、単純にnameに正しくバリデーションが付いていないのではないでしょうか？  
たとえば`validates`ではなく、`validate`になっているとか。（僕もこれに何度かハマったことがあります）

というわけで一度Userの実装も追記してください。

あと、デバッグの方法としてrails consoleでトライアンドエラーを繰り返すというやり方があります。

[code]

    u = User.new 
    u.valid?
    u.errors
    
[/code]

みたいにしながらコンソール上でnameの値をいろいろ変えてみてください。

不可解な動きをする場合はコンソールの操作内容も追記してください。


CC BY-SA 3.0
2015-03-23T19:22:26.343
8284
2015-03-23T19:22:26.343
85
8270
answer

[code]

    describe "when password is not present" do
        before do
            @user = User.new(name: "Example User", email: "user@example.com",
                password: " ", password_confirmation: " ")
        end
        it { should_not be_valid }
    end
    
[/code]

`has_secure_password`自身は文字長や文字種はチェックしておらず空白文字1文字だけのパスワードでも許容するので、`has_secure_password`を追加しただけなのであれば`password`と`password_confirmation`ともに空白一文字を指定している上記のテストは失敗するのではないでしょうか。

* * *

コメントで指摘があったとおり、Rails4.2より前は空白のみのパスワードが検証に通らないので「テストが失敗する」のを再現するのであれば4.2より前のバージョンを使えばいいということになります。


CC BY-SA 3.0
2015-03-24T00:59:18.340
8290
2015-03-24T05:31:44.937
2015-03-24T05:31:44.937
5793
5793
8270
answer