Search code examples
mysqlruby-on-railsauto-increment

Ruby on Rails: Custom Alphanumeric id based on another field and Auto increment it


Before starting I must say I'm new to Ruby on rails.

I have a model named Vendor. I want to have a field vendorid, which should be a alphanumeric field. I want to auto-increment it.

I also have a city, which is drop down select field in the same model. I want my vendorid to use that field in its value.

For example: If my first entry of Vendors has the city HYD, I would like my vendorid to be HYD001, If the next entry has city DEL, then vendorid should be DEL001, else if it has HYD as its city again then it should be HYD002.

Upon searching a lot on the web I found the gem protokoll. But I think even that does not help my situation.

class Vendor < ActiveRecord::Base    
    protokoll :vendorid, :pattern => city + "###"
end

I have also tried:

:pattern => "#{city}###" :pattern => self.city + "###"

It throws me an error "undefined method `city' for #Class:0xb61c4150"

Thanks for any help.


Solution

  • Forgetting about Protokoll for the moment, i think this should work.

    class Vendor
      before_create :set_unique_vendorid
    
      def set_unique_vendorid
        if last_vendor = Vendor.find(:last, :order => "id", :conditions => ["vendorid like ?", "#{self.city}%"])
          last_vendorid_number = last_vendor.vendorid.scan(/\d+$/).first.to_i
          new_vendorid_number = last_vendorid_number + 1
        else
          new_vendorid_number = 1
        end
        self.vendorid = "#{self.city}#{sprintf("%03d", new_vendorid_number)}"
      end
    

    the sprintf bit will convert new_vendorid_number into a three-digit string (eg "002") which it looked like you had as a requirement.

    NOTE: you have a potential race condition here if you have a server running multiple instances of rails, and two of them try to create a new Vendor object at the same time. But if you get to the point where you're so successful you need to worry about this then you can refactor it with transactions or something :O