【问题标题】:Validating uniqueness of one attribute across two separate columns在两个单独的列中验证一个属性的唯一性
【发布时间】:2016-06-15 18:11:10
【问题描述】:

我需要验证两个字段的唯一性。

型号

:name
:original_url #(this cannot match any url or original_url)
:url #(this cannot match any url or original_url)

我可以单独验证每一个

validates_uniqueness_of :name, scope: {:url, :original_url}

但我不知道如何才能保护这两个领域。我也有点担心性能(该表有 2m 条记录)。这些字段已编入索引,所以我希望这就足够了。

知道最好的方法是什么吗?

【问题讨论】:

    标签: ruby-on-rails validation activerecord


    【解决方案1】:

    最好的方法是在数据库级别和 Rails 模型中。我可以在后者方面为您提供帮助,希望有人也可以通过 SQL 添加它。由于您没有指定名称,因此我将其保留在“模型”上下文中:

    在你的 model.rb 文件中:

    validate :ensure_unique_for_both_cols
    
    def ensure_unique_for_both_cols
      if self.original_url || self.url
        #Ensure no record matching this exists in either field
        unless Model.where("original_url = ? OR url = ?",self.original_url, self.url).empty?
           self.errors.add(:base, "The url must be unique!")
        end
      end     
    end
    

    【讨论】:

    • 这不太行。这将测试 original_url 是否匹配任何 original_urls,或者 url 是否匹配任何 url。我需要测试来检查 original_url 是否与任何 original_url 或 ad_url 匹配,同样适用于 url。
    【解决方案2】:

    感谢上面的 bkunzi 为我指明了正确的方向。

    验证:ensure_urls_unique

    def ensure_urls_unique
      urls = [self.url, self.original_url].compact # To allow 'nil' to match
      if Job.where("original_url IN (?) OR ad_url IN (?)",urls, urls).where(name:self.name).where.not(id:self.id).exists?
        self.errors.add(:base, "The urls must be unique!")
      else
        return true
      end
    end
    

    值得注意的是 .exists 吗?性能比 .empty 好一点?在大型样本集或您可能会得到匹配的地方。

    【讨论】:

      猜你喜欢
      • 2015-07-04
      • 2012-10-10
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 1970-01-01
      相关资源
      最近更新 更多