在字符串的一部分上验证ActiveRecord中的单一性

时间:2016-03-07 22:57:15

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

假设我在registration_id模型上有Dummy属性。 它的数据类型是字符串。 它的长度可以是10-14个字符,但我想在最后10个字符上进行唯一性验证。 (奇怪但真实)

现在我该如何实现这个目标?

我的想法:

  1. last_ten_chars_registration_id表中创建另一个属性Dummy以保存最后10个字符,并在此属性上添加唯一性。 (由于Computed属性显然不适用于唯一性验证)

  2. 我可以创建自定义验证器并编写查询。 我不确定(可能是like查询)

  3. 有人能建议我有更好的方法来实现这个目标吗?

2 个答案:

答案 0 :(得分:0)

您可以使用这样的自定义验证器。

class Dummy < ActiveRecord::Base
  validates_with RegistrationValidator, :fields => [:registration_id]

  # Whatever else...
end

class RegistrationValidator < ActiveModel::Validator
  def validate(record)
    reg_id = record.registration_id.last(10).join
    if Dummy.where('registration_id LIKE ?',"%#{reg_id}")
      record.errors[:registration_id] << "Registration ID taken!"
    end
  end
end

答案 1 :(得分:0)

与GoGoCarl相同,我也认为它在很大程度上取决于您所需的性能。我认为自定义查询(不使用LIKE而是使用RIGHT(registration_id, 10)函数,至少在MySQL中),除非Dummy表很大或者您需要查询超快。在这种情况下,我也会使用最后10个字符和附带的db索引来执行特殊列。

一个实用的解决方案可能是首先去自定义查询路由,因为它似乎更容易实现给我,后来,如果性能开始受到影响,请切换到特殊列。

你也可以做自己的基准测试,例如:使用您期望的记录数填充测试Dummy表,如果您的表现没有问题,请自行查看。

关于解决方案类似的字符串SQL函数性能,请参见此related SO question