###パスワードの最小文字数
パスワードを簡単に当てられないようにするために、パスワードの最小文字数を設定
しておくことは一般に実用的です。
Railsでパスワードの長さを設定する方法はたくさんありますが、今回は簡潔にパスワードが空でない
ことと最小文字数(6文字)
の2つを設定しましょう。
パスワードの長さが6文字以上であることを検証するテストを示します。
####パスワードの最小文字数をテストする
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
.
.
.
test "password should be present (nonblank)" do
@user.password = @user.password_confirmation = " " * 6
# パスワードの空白が六文字
assert_not @user.valid?
# バリデーションは認められないよね?
end
test "password should have a minimum length" do
@user.password = @user.password_confirmation = "a" * 5
# 文字が五文字
assert_not @user.valid?
# このパスワードも認められないよね?
end
end
次のような多重代入(Multiple Assignment)
を使っていることに注目してください。
@user.password = @user.password_confirmation = "a" * 5
パスワードとパスワード確認に対して同時に代入をしています。
maximum
を使ってユーザー名の最大文字数を制限
していましたが、これと似たような形式のminimum
というオプションを使って、最小文字数のバリデーション
を実装することができます。
validates :password, length: { minimum: 6 }
空のパスワードを入力させないために、存在性のバリデーション(6.2.2)も一緒に追加します。
結果として、Userモデルのコードはリスト 6.43のようになります。
ちなみにhas_secure_password
メソッドは存在性のバリデーション
もしてくれるのですが、これは新しくレコードが追加されたときだけ
に適用される性質を持っています。
したがって、例えばユーザーが' '(6文字分の空白スペース)といった文字列をパスワード欄に入力して更新しようとすると、バリデーションが適用されずに更新されてしまう問題が発生してしまうのです。
class User < ApplicationRecord
before_save { self.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, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: true
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
ubuntu:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 22618
11/11: [============================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.06481s
11 tests, 19 assertions, 0 failures, 0 errors, 0 skips
###演習
1.有効な名前とメールアドレスでも、パスワードが短すぎるとuserオブジェクトが有効にならないことを確認してみましょう。
2.上で失敗した時、どんなエラーメッセージになるでしょうか? 確認してみましょう。
>> user
=> #<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.password = "aa"
=> "aa"
>> user.save
(0.1ms) SAVEPOINT active_record_1
User Exists? (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? AND "users"."id" != ? LIMIT ? [["email", "michael@example.com"], ["id", 1], ["LIMIT", 1]]
(0.1ms) ROLLBACK TO SAVEPOINT active_record_1
=> false
>> user.valid?
User Exists? (0.2ms) 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 is too short (minimum is 6 characters)"]