Rails 3 - 添加索引failafe,以确保可能重复的唯一性

时间:2012-02-25 01:31:04

标签: ruby-on-rails validation before-save

我有一个问题,我一直无法找到答案。我很抱歉,如果它非常简单或明显,我在这里是一个完全的初学者。

所以我在我的数据库中有一个名为:client_code的列,它在模型中定义为第一个字符:first_name和:last_name的下行连接。因此,例如,如果我提取一个新表单并为:first_name输入'John',并为:last_name输入'Doe':client_code自动赋予'jdoe'的值。这是模型代码的相关部分:

class Client < ActiveRecord::Base

  before_validation :client_code_default_format
  validates_presence_of :first_name, :last_name, :email
  validates_uniqueness_of :client_code

  ...


  def client_code_default_format
    self.client_code = "#{first_name[0]}#{last_name}".downcase
  end
end

我想在此代码中添加一些内容,以便在有人输入具有相同名称的不同客户端时,它不会失败唯一性验证,而是创建一个稍微修改过的:client_code('jdoe2' , 例如)。我可能想出如何为所有这些添加索引,但我更愿意在重复的情况下仅包含数字作为故障保护。谁能指出我正确的方向?

2 个答案:

答案 0 :(得分:1)

计算具有相同Client的当前匹配client_code对象的数量应该有效

def client_code_default_format
  preferred_client_code = "#{first_name[0]}#{last_name}".downcase
  count = Client.count(:conditions => "client_code = #{preferred_client_code}")
  self.client_code = count == 0 ? preferred_client_code : preferred_client_code + count
end

答案 1 :(得分:1)

非常感谢@Dieseltime的回复。我接受了他的建议,并通过一些小的改动得到了我想要的功能:

before_validation :format_client_code
validates_presence_of :first_name, :last_name, :email, :company_id
validates_uniqueness_of :client_code

...

def format_client_code
  unless self.client_code != nil
    default_client_code = "#{first_name[0]}#{last_name}".downcase
    count = Client.count(:conditions => "client_code = '#{default_client_code}'")
    if count == 0
      self.client_code = default_client_code
    else
      self.client_code = default_client_code + (count + 1).to_s
    end
  end
end