【问题标题】:Conditional case_sensitive validation in model模型中的条件 case_sensitive 验证
【发布时间】:2020-06-17 17:17:26
【问题描述】:

我有一个模型验证,如下所示

validates :value, presence: true, allow_blank: false, uniqueness: { scope: [:account_id, :provider] }

我想在唯一性内再添加一个区分大小写的条件,如下所示

validates :value, presence: true, allow_blank: false, uniqueness: { scope: [:account_id, :provider], case_sensitive: :is_email? }

def is_email?
  provider != email
end

简而言之,当电子邮件提供商不是电子邮件时,它不应该验证 case_sensitive,但目前,它不起作用,它只期望 true 或 false,而不是任何方法或任何条件。

如何在 Rails 中实现这一点?我已经编写了自定义验证,因为它不起作用。

更新

如果我像下面这样添加另一个验证

validates_uniqueness_of :value, case_sensitive: false, if: -> { provider == 'email' }

两次:value=>["has already been taken", "has already been taken"]给我同样的错误

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    case_sensitive 的特定情况下,传递给选项的值将始终与其 truthy 值进行比较。

    正如您在UniquenessValidator 类中看到的那样,当建立关系时,它使用传递的选项来检查case_sensitive 的值是否为真(不是假也不是零),如果是,则采用@ 987654325@条件分支:

    def build_relation(klass, attribute, value)
      ...
        if !options.key?(:case_sensitive) || bind.nil?
          klass.connection.default_uniqueness_comparison(attr, bind, klass)
        elsif options[:case_sensitive] # <--------------------------------- sadly, this returns true for :is_email?
          klass.connection.case_sensitive_comparison(attr, bind)
        else
          # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
          klass.connection.case_insensitive_comparison(attr, bind)
        end
      ...
    end
    

    当您将方法名称 is_email? 传递给 case_sensitive(实际上是一个符号)时,条件采用该分支。

    tl;博士;。您必须始终将truefalsecase_sensitive 一起使用。

    【讨论】:

    • 不用说,您可能需要重新考虑验证新记录唯一性的方式,因为众所周知,这种方式具有硬性能 .
    • 感谢您的深入解释。是的,我知道这会产生性能问题。因此,我将仅在验证之前将值小写,并从唯一性中删除区分大小写的选项。
    • 虽然,我认为 rails 应该提供条件验证 case_sensitive 的选项。 :D
    • 不错!是的,我想是的,知道这种行为在 ActiveRecord 的其他部分可用并且不适用于 case_sensitive,这非常令人困惑。
    猜你喜欢
    • 2014-08-29
    • 1970-01-01
    • 2021-08-05
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多