RubyOnRails

Ruby on Rails チュートリアル学習記録

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
>>