Ruby on Railsチュートリアル学習記録です。
一度で理解できないポイントがいくつかあるので、咀嚼する意味を含めてアウトプットしております。
6.2.5 一意性を検証する
今日は、6.2.5の実験をしていますが、一意性の検証用のコードは、rails consoleのアウトプットと合わせて読むと理解しやすいと思っています。
minitestからの一意性検証部分を抜粋
upcaseしているため一意性は確保されています。
@user.saveで一度データベースへ登録(INSERT)後に、duplicate_user.valid?でデータベース内のデータの重複チェックを実施。
これは、falseが返るので、assert_notで成功するので重複チェックテストが通るという理由ですね。
うん、アウトプットは理解を深めますね。
user_test.rb
test "email addresses should be unique" do
duplicate_user = @user.dup
duplicate_user.email = @user.email.upcase
### データベース内の存在性確認のため、一度INSERTしている
@user.save
assert_not duplicate_user.valid?
end
Userモデルコード
app/models/user.rb
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
end
rails consoleアウトプット
user_test.rbと同等の状態を再現しています。
最後にfalseになることを確認するのがポイントです。
$ rails console --sandbox
Running via Spring preloader in process 459
Loading development environment in sandbox (Rails 5.1.4)
Any modifications you make will be rolled back on exit
>> user = User.create(name: "Example User", email: "user@example.com")
(0.1ms) SAVEPOINT active_record_1
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ? [["email", "user@example.com"], ["LIMIT", 1]]
SQL (2.2ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Example User"], ["email", "user@example.com"], ["created_at", "2017-12-19 02:51:04.441985"], ["updated_at", "2017-12-19 02:51:04.441985"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 1, name: "Example User", email: "user@example.com", created_at: "2017-12-19 02:51:04", updated_at: "2017-12-19 02:51:04">
>> duplicate_user = user.dup
=> #<User id: nil, name: "Example User", email: "user@example.com", created_at: nil, updated_at: nil>
>> duplicate_user.email = user.email.upcase
=> "USER@EXAMPLE.COM"
>> duplicate_user.valid?
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ? [["email", "USER@EXAMPLE.COM"], ["LIMIT", 1]]
=> false
>>