###ユーザーがセキュアなパスワードを持っている
Userモデルにpassword_digest
属性を追加し、Gemfileにbcryptを追加したことで、ようやくUserモデル内でhas_secure_password
が使えるようになりました。
####Userモデルにhas_secure_passwordを追加する
class User < ApplicationRecord
before_save { email.downcase! }
# データベースに保存する前に処理をする。
# 入力されたメールアドレスを小文字にする。
validates :name, presence: true, length: { maximum: 50 }
#属性はname,属性の存在を検証、 最大50字まで
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
#最大255字まで
format: { with: VALID_EMAIL_REGEX },
uniqueness: true
#???
has_secure_password
#セキュアなパスワードの実装
end
red と記しておいたように、まだテストは落ちたままになっているはずです。
ubuntu:~/environment/sample_app (modeling-users) $ rails t
Running via Spring preloader in process 10116
Started with run options --seed 39785
ERROR["test_should_get_home", #<Minitest::Reporters::Suite:0x000055a5c42ddc40 @name="StaticPagesControllerTest">, 0.01687353799934499]
test_should_get_home#StaticPagesControllerTest (0.02s)
NameError: NameError: undefined local variable or method ` has_secure_password' for #<Class:0x000055a5c42bc108>
Did you mean? has_secure_password
app/models/user.rb:13:in `<class:User>'
app/models/user.rb:1:in `<main>'
17/17: [============================] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.07316s
17 tests, 34 assertions, 0 failures, 1 errors, 0 skips
NameError: undefined local variable or method ` has_secure_password'
has_secure_passwordに使う変数、メソッドが見つからないらしい。
テストが失敗する理由は、has_secure_password
には、仮想的なpassword属性とpassword_confirmation属性に対してバリデーションをする機能も(強制的に)追加
されているからです。
しかしテストでは、@user 変数にこのような値がセットされておりません
def setup
@user = User.new(name: "Example User", email: "user@example.com")
end
####パスワードとパスワード確認を追加する
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar")
end
.
.
.
end
変数を追加した。
ubuntu:~/environment/sample_app (modeling-users) $ rails t
Running via Spring preloader in process 12573
Started with run options --seed 33971
17/17: [============================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.38901s
17 tests, 36 assertions, 0 failures, 0 errors, 0 skips
全角スペースでエラーが出た。疲れた。
###演習
- この時点では、userオブジェクトに有効な名前とメールアドレスを与えても、valid?で失敗してしまうことを確認してみてください。
2.なぜ失敗してしまうのでしょうか? エラーメッセージを確認してみてください。
>> user = User.find(1)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com", created_at: "2021-09-23 05:29:52", updated_at: "2021-09-23 05:29:52", password_digest: nil>
>> user.valid?
User Exists? (0.8ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? AND "users"."id" != ? LIMIT ? [["email", "michael@example.com"], ["id", 1], ["LIMIT", 1]]
=> false
>> user.errors.full_messages
=> ["Password can't be blank"]
パスワードがないみたい。