I noticed on the docs it says: Previous versions of FriendlyId appended a numeric sequence to make slugs unique, but this was removed to simplify using FriendlyId in concurrent code.
Is there any way to revert back to this format? My model only has name
so there aren't any other viable slug candidates and (time
or date
wouldn't make sense in this case for slug candidates).
How can I change this (current format):
car.friendly_id #=> "peugeot-206"
car2.friendly_id #=> "peugeot-206-f9f3789a-daec-4156-af1d-fab81aa16ee5"
car3.friendly_id #=> "peugeot-206-f9dsafad-eamj-2091-a3de-fabsafafdsa5"
Into this:
car.friendly_id #=> "peugeot-206"
car2.friendly_id #=> "peugeot-206-1"
car3.friendly_id #=> "peugeot-206-2"
Old behaviour was implemented in special module. But at the moment it has not been released yet. So, if you want to restore old behaviour you can switch friebdly_id
in your Gemfile
on Github and add sequentially_slugged
to the modules list.
I realize you said
(time or date wouldn't make sense in this case for slug candidates)
But in assuming you we're only referring to the string format of time and not unix which is a numeric sequence then I came up with this workaround to your problems/concerns:
- your model only has name attribute
- you can't use id to append to the slug because it hasn't been created yet
- you want the slugs to be uniq and incrementing
- you don't want to use UUID
# app/models/car.rb
class Car < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
def normalize_friendly_id(string)
incremented_number = (Time.now.to_f * 1000000).to_i
"#{super}-#{incremented_number}"
end
end
So now this works
car1 = Car.create(name: "peugeot")
car2 = Car.create(name: "peugeot")
car3 = Car.create(name: "peugeot")
car1.friendly_id #=> "peugeot-1451368076324115"
car2.friendly_id #=> "peugeot-1451368076457560"
car3.friendly_id #=> "peugeot-1451368076460087"
Note: the numbers are incrementing
Time.now.to_f * 1000 would be miliseconds and I'm using
Time.now.to_f * 1000000 which is MICROSECONDS <- that's one millionth of a second. It's NOT going to be created at the same time and therefore won't run into slug conflicts. And if someone out there thinks it could then just add a few more zeros to that multiplier.
There are good reasons that "serial number" was replaced by UUID (race conditions).
I normally use an additional slug candidate with the ID, that is maintained uniq by the db and much shorter than an UUID:
[ [:name], [:name, :id] ]