I am using friendly_id gem for slugging my models. Since the slug has to be unique when i enter the same data to check i get a long hashed appending in the slug.
Agreed, it seems like pretty rough behavior.
If you look at code of friendly_id/slugged.rb
, there are 2 functions handing conflicts resolution logic:
def resolve_friendly_id_conflict(candidates)
candidates.first + friendly_id_config.sequence_separator + SecureRandom.uuid
end
# Sets the slug.
def set_slug(normalized_slug = nil)
if should_generate_new_friendly_id?
candidates = FriendlyId::Candidates.new(self, normalized_slug || send(friendly_id_config.base))
slug = slug_generator.generate(candidates) || resolve_friendly_id_conflict(candidates)
send "#{friendly_id_config.slug_column}=", slug
end
end
So, the idea is just to monkey patch it. I see 2 options:
Just patch resolve_friendly_id_conflict
, add your random suffix.
Change logic of both methods with intention of trying all candidates until slug_generator.generate(candidates)
returns something not empty. If all candidates give nil
then fallback to resolve_friendly_id_conflict
method.
Using this technique you can use slug candidates to append model's id
when slug is not unique.
Ideally, it would be nice if gem's authors added a config option to handle unique slugs resolution (method symbol or proc taking generator and candidates as params) or just check if model responds to some method.
Besides, in some use cases unique slugs resolution in not needed at all. For example, if we just want to rely on validates_uniqueness_of :slug
or uniqueness validation of candidates.