Search code examples
ruby-on-railsuniqueslugpermalinksvalidates-uniqueness-of

Rails: Append number to permalink, if permalink already taken


I would like to give John Doe the permalink john-doe-2, if there already is a john-doe-1. The number should be the next free one to be appended ("john-doe-n")

Currently my permalinks are generated the usual way:

before_validation :generate_slug  
private
def generate_slug   
  self.permalink = self.name.parameterize
end

How to implement a validates_uniqueness_of-like method, that adds this kind of number to self.permalink and then saves the user normally?


Solution

  • First of all, ask yourself: Is there a simpler way to do this? I believe there is. If you're already willing to add numbers to your slug, how about always adding a number, like the ID?

    before_validation :generate_slug
    
    private
    def generate_slug
      self.permalink = "#{self.id}-#{self.name.parameterize}"
    end
    

    This is a very robust way of doing it, and you can even pass the slug directly to the find method, which means that you don't really need to save the slug at all.

    Otherwise, you can just check if the name + number already exists, and increment n by 1, then recheck, until you find a free number. Please note that this can take a while if there are a lot of records with the same name. This way is also subject to race conditions, if two slugs are being generated at the same time.