2

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?

David
  • 937
  • 1
  • 12
  • 22

1 Answers1

3

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.

sarahhodne
  • 9,796
  • 3
  • 39
  • 44
  • Thanks dvyjones, in this user-centric vanity case it would probably be unfortunate to have a profile permalink associated to its creation date: **user/4208-john-doe** would obviously be newer to the site than **user/1-john-doe**. So I would opt for your second solution, how would you go about this in the code exactly? – David Jul 10 '11 at 16:44
  • 1
    Well, john-doe-1 would also be newer than john-doe-2. But to answer your question, I believe this will work: https://gist.github.com/456d87a12bdd6aa30779. I haven't tested it though. – sarahhodne Jul 10 '11 at 17:28
  • Your gist is working, just prepended the model name ("User") to your _where_ queries and added **if self.name_changed?** to the method. To prevent new numbers from being added to the same user when saving. – David Jul 11 '11 at 16:44
  • Just a fair warning though: This will get slower as more users with the same name registers. – sarahhodne Jul 11 '11 at 19:05