Rails 3 — добавление отказоустойчивого индекса для обеспечения уникальности потенциальных дубликатов

У меня есть вопрос по рельсам, на который я не смог найти ответ самостоятельно. Прошу прощения, если это очень просто или очевидно, я здесь полный новичок.

Итак, у меня есть столбец в моей базе данных с именем :client_code, который определен в модели как конкатенация первого символа :first_name и :last_name в нижнем регистре. Так, например, если я открываю новую форму и ввожу «Джон» для :first_name и «Доу» для :last_name, :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', например ). Я, вероятно, мог бы понять, как добавить индекс ко всем из них, но я бы предпочел включать только числа в качестве отказоустойчивости в случае дубликатов. Может кто-то указать мне верное направление?


person desperatethelark    schedule 25.02.2012    source источник


Ответы (2)


Вычисление количества текущих совпадающих объектов 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
person Dieseltime    schedule 25.02.2012
comment
Спасибо за ответ! Это было почти то, что мне было нужно. Я опубликую свой рабочий код как отдельный ответ. - person desperatethelark; 26.02.2012

Большое спасибо @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
person desperatethelark    schedule 25.02.2012