Ruby on Rails教程 - 奇怪的使用upcase / downcase和case-insensitivity

时间:2013-08-24 19:41:21

标签: ruby-on-rails ruby rspec railstutorial.org

通过Michael Hartl为Ruby on Rails提供优秀的tutorial。我正在创建一个检查重复电子邮件地址的测试,我对他使用大写,小写和不区分大小写的检查感到有些困惑。

测试(代码清单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)中,他设置了区分大小写 off

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

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

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

before_save { self.email = email.downcase }

这很有道理,因为你想在数据库中使用小写。但我很困惑为什么他在测试中使用大写,因为保存将把电子邮件地址转换为小写无论如何。我错过了一些明显的东西吗?

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

检查@user.email.upcase无效可确保此值的唯一性,无论情况如何。 当你写uniqueness: { case_sensitive: false }时你强迫唯一性,无论情况如何:“foo”相当于“fOO”。 至于before_save,设置它可能有点过分,而且验证不敏感,但至少它会向您展示目标: 电子邮件必须是唯一的,无论是哪种情况,都是验证。另一方面,您将所有内容存储为小写,这是数据部分。

答案 2 :(得分:1)

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

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