Reputation: 4526
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"
Upvotes: 0
Views: 1353
Reputation: 9145
Example use of sequentially_slugged
class Pipeline < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :sequentially_slugged
belongs_to :user
scope :published, -> { where(published: true) }
end
Upvotes: 1
Reputation: 2584
create a file in /config/initializers/slugged.rb
This works for me
module FriendlyId::Slugged
def resolve_friendly_id_conflict(candidates)
column = friendly_id_config.slug_column
separator = friendly_id_config.sequence_separator
slug = normalize_friendly_id(candidates.first)
sequence = self.class.where("#{column} like '#{slug}#{separator}%'").count + 2
"#{slug}#{separator}#{sequence}"
end
end
Output will be
for first record => firstname-lastname
for second record => firstname-lastname-2
for third record => firstname-lastname-3
Upvotes: 0
Reputation: 562
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.
Upvotes: 3
Reputation: 4639
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:
# 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.
Upvotes: 2
Reputation: 8658
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] ]
Upvotes: -1