【问题标题】:Ruby on Rails Tutorial -- strange uses of upcase/downcase and case-insensitivityRuby on Rails 教程——大写/小写和不区分大小写的奇怪用法
【发布时间】:2013-08-24 19:41:20
【问题描述】:

通过 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) 中,他设置了区分大小写关闭

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

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

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

before_save { self.email = email.downcase }

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-06
          • 1970-01-01
          • 2013-03-06
          • 2020-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多