0

Michael Hartl Ruby on Rails チュートリアルに従っています。テストに失敗して、セクション 6.3 で立ち往生しています。コードは空白のパスワードを検証する必要がありますが、パスワードを使用して User オブジェクトを作成し、パスワード フィールドを空白に変更するvalid?と、テスト仕様によると予期されていない true が返されます。何か不足していますか?

protected_attributes私はgemをインストールしなければなりませんでした。私は、この gem を使用して、チュートリアル コードを変更せずに実行することを好みます。

実行すると、次のbundle exec rspec specようになります。

rspec ./spec/models/user_spec.rb:90 # User when password confirmation is nil 
rspec ./spec/models/user_spec.rb:80 # User when password is not present 

これが私のファイルです。

ユーザー.rb:

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation
  has_secure_password

  before_save { |user| user.email = email.downcase }

  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence:   true,
                    format:     { with: VALID_EMAIL_REGEX },
                uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 6 }
  validates :password_confirmation, presence: true
end

user_spec.rb (失敗したテストのみ):

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

  describe "when password confirmation is nil" do
    before { @user.password_confirmation = nil }
    it { should_not be_valid }
  end

そして、コンソールで実行したいくつかのテストを次に示します。

max@top:~/prog/ruby/railstut$ rails c --sandbox
Loading development environment in sandbox (Rails 4.0.0.rc1)
Any modifications you make will be rolled back on exit
irb(main):001:0> # Should return true.
irb(main):002:0* User.new(name: "Example User", email: "user@example.com",
irb(main):003:1*                      password: "foobar", password_confirmation: "foobar").valid?
  User Exists (1.8ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('user@example.com') LIMIT 1
=> true
irb(main):004:0> 
irb(main):005:0* # Should return false.
irb(main):006:0* User.new(name: "Example User", email: "user@example.com",
irb(main):007:1*                      password: "", password_confirmation: "foobar").valid?
  User Exists (0.8ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('user@example.com') LIMIT 1
=> false
irb(main):008:0> 
irb(main):009:0* # Oops. Expecting false.
irb(main):010:0* user = User.new(name: "Example User", email: "user@example.com",
irb(main):011:1*                      password: "foobar", password_confirmation: "foobar")
=> #<User id: nil, name: "Example User", email: "user@example.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$ygkdtuJYF89ysbD86ZcO9ugiQZ0/FxOKvj87zEegJq.f...">
irb(main):012:0> 
irb(main):013:0* user.password = ""
=> ""
irb(main):014:0> 
irb(main):015:0* user.valid?
  User Exists (0.5ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('user@example.com') LIMIT 1
=> true
4

2 に答える 2

0

あなたのvalidates :password, presence: true検証は、Rails 4 の has_secure_password によって追加された検証と競合する可能性があると思います。ここでRyan B の回答を参照してください。

また、has_secure_password は既に実行validates :password_confirmation, presence: trueされているはずなので、モデルからその行を削除する必要があります。

于 2013-05-29T04:23:26.350 に答える