通过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 }
这很有道理,因为你想在数据库中使用小写。但我很困惑为什么他在测试中使用大写,因为保存将把电子邮件地址转换为小写无论如何。我错过了一些明显的东西吗?
答案 0 :(得分:5)
在我看来,通过转换为大写,并将数据存储为小写,您确保它们不相等,因此验证器的“case_sensitive:false”部分将真正进行测试。
答案 1 :(得分:2)
检查@user.email.upcase
无效可确保此值的唯一性,无论情况如何。
当你写uniqueness: { case_sensitive: false }
时你强迫唯一性,无论情况如何:“foo”相当于“fOO”。
至于before_save
,设置它可能有点过分,而且验证不敏感,但至少它会向您展示目标:
电子邮件必须是唯一的,无论是哪种情况,都是验证。另一方面,您将所有内容存储为小写,这是数据部分。
答案 2 :(得分:1)
测试是(有点默默地,它不在描述中)断言在检查唯一性时忽略大小写。对于一般的电子邮件地址,这是一种明智的行为。
存储数据的小写“规范化”,加上从验证中删除区分大小写,似乎有点过分,但是由于验证时的事件顺序而不是保存,可能。无论哪种方式,具有忽略大小写的唯一性约束,同时将电子邮件地址规范化为小写存储,这是自洽的。