【问题标题】:Efficiently validate uniqueness on elements of text field有效验证文本字段元素的唯一性
【发布时间】:2016-08-08 00:06:19
【问题描述】:

所以我有一个product 模型,它的文本属性为换行符分隔tags。这背后的原因是,每天都有一个查询遍历这些字段中的每一个,并按产品构建正则表达式,我希望它尽可能快。产品大约每隔几个月才添加或更新一次,因此验证不需要那么高效,但我希望尽可能好,因为它可以得到之前的限制。

到目前为止,我想出的是这样的:

def build_regex_string
  '(' + tags.gsub(/(\r?\n(?!$))/,'|').gsub(/(\r?\n)/,'') + ')'
end

def validate_tags_are_unique
  Product.where.not(id: id).each do |product|
    tags_regex = Regexp.new(product.build_regex_string)
    return false if tags_regex.match(tags)
  end
end

我使用正则表达式主要是因为它是我已经拥有的方法。我试图研究将验证直接写入 pSQL 中的迁移是否是一个更好的主意?我对此并不精通。我研究的另一件事是改用数组类型,但我还没有找到一个 ActiveRecord 验证,它可以用数组做我想要的,我不想浪费时间构建和取消构建数组。最后,我考虑了将正则表达式实际存储在数据库中的方法,但看起来无论哪种方式我都必须从字符串中构建正则表达式。

【问题讨论】:

  • 您当前需要优化的代码有多慢?

标签: ruby-on-rails ruby postgresql validation activerecord


【解决方案1】:

你为什么不使用 Ruby 来做这件事呢?在 Ruby 中就是这么简单。

def validate_tags_are_unique
  self_tags = tags.split(/\n/)
  Product.where.not(id: id).tags.all?{ |t| (self_tags - t.split(/\n/)).empty? }
end

【讨论】:

  • 它不能正常工作,因为 Product.where.not(id: id) 返回的集合没有标签属性。
  • Product.where.not(id: id).all? { |产品| (self_tags & prod.tags.split(/\n/)).empty? } 更正确(所有产品与当前产品的标签没有共同标签)
  • 我修好了。谢谢!
  • "-" 运算符在这里不起作用。 ["a", "b", "c"] - [] => ["a", "b", "c"], ["a", "b", "c"] - ["b" ] => ["a", "c"], ["a", "b", "c"] - ["a", "b", "c"] => [].
猜你喜欢
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 2011-05-01
  • 2019-03-24
  • 1970-01-01
  • 2011-08-07
  • 2017-05-29
相关资源
最近更新 更多