desperatethelark
desperatethelark

Reputation: 23

Rails 3 - adding an index failsafe to ensure the uniqueness of would-be duplicates

I have a rails question that I have been unable to find an answer for on my own. I apologize if it's very simple or obvious, I'm a complete beginner here.

So I have a column in my db called :client_code, which is defined in the model as the down-cased concatenation of the first character of :first_name, and :last_name. So for instance, if I pull up a new form and enter 'John' for :first_name, and 'Doe' for :last_name, :client_code is automatically given the value of 'jdoe'. Here's the relevant portion of the model code:

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

I would like to add something to this code so that, in the event that someone enters a different client with the same exact name, it does't fail the uniqueness validation but instead creates a slightly modified :client_code ('jdoe2', for example). I could probably figure out how to add an index to all of them, but I would prefer to only include numbers as a failsafe in the case of duplicates. Can anyone point me in the right direction?

Upvotes: 0

Views: 73

Answers (2)

desperatethelark
desperatethelark

Reputation: 23

Many thanks to @Dieseltime for his response. I took his suggestion and was able to get the functionality I wanted with some minor changes:

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

Upvotes: 1

Dieseltime
Dieseltime

Reputation: 972

Calculating the number of current matching Client objects with the same client_code should work

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

Upvotes: 1

Related Questions