0

阅读 Michael Hartl 的 Ruby on Rails 优秀教程。我正处于他创建一个检查重复电子邮件地址的测试的地步,我对他使用大写、小写和不区分大小写的检查有点困惑。

测试(清单 6.17)如下所示:

describe User do
  before do
    @user = User.new(name: "Example User", email: "user@example.com")
  end
  .
  .
  .
  describe "when email address is already taken" do
    before do
      user_with_same_email = @user.dup
      user_with_same_email.email = @user.email.upcase
      user_with_same_email.save
    end

    it { should_not be_valid }
  end
end

注意对 的调用upcase。一切都好。但是在他的有效性检查(6.18)中,他设置了区分大小写。

validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }

什么?如果他要进行不区分大小写的验证,为什么要将副本转换为大写?

最后,在 6.20 中,他设置了一个before_save将新用户的电子邮件转换为小写的块。

before_save { self.email = email.downcase }

这很有意义,因为您希望数据库中使用小写字母。但是我对他为什么在测试中使用大写感到困惑,因为无论如何保存都会将电子邮件地址转换为小写。我错过了一些明显的东西吗?

4

3 回答 3

5

在我看来,通过转换为大写并将数据存储为小写,您可以确保它们不等价,因此验证器的“case_sensitive:false”部分将真正被测试。

于 2013-08-24T19:44:22.960 回答
2

检查@user.email.upcase无效可确保此值的唯一性,无论情况如何。当你写uniqueness: { case_sensitive: false }你强制唯一性,不管是什么情况:“foo”等价于“fOO”。至于设置before_save它可能有点矫枉过正并且不区分验证大小写,但至少它向您展示了目标:电子邮件必须是唯一的,无论如何,这就是验证。另一方面,您存储所有小写字母,这是数据部分。

于 2013-08-24T19:47:10.633 回答
1

测试是(有点沉默,它不在描述中)断言在检查唯一性时会忽略这种情况。这对于一般的电子邮件地址来说是一种明智的行为。

存储数据的小写“规范化”,加上从验证中删除区分大小写,似乎有点矫枉过正,但由于验证而不是保存时的事件顺序,可能需要。无论哪种方式,具有忽略大小写的唯一性约束是自洽的,同时将电子邮件地址规范化为小写以进行存储。

于 2013-08-24T19:46:10.287 回答