FriendlyId is an awesome gem for slugging and permalinking for Active Record. It works like a charm except one case: when you set friendly_id field in a before_validation callback.

Here’s an example:

class User < ActiveRecord::Base
  extend FriendlyId

  friendly_id :login, use: %i( history finders )

  before_validation :set_login

  def set_login
    # This weird method will just generate a random string
    self.login = (0...8).map { (65 + rand(26)).chr }.join
  end
end

User.new.save!
User.last.login #=> 'bhkcjvrd'
User.last.to_param #=> user id
User.last.slug #=> ''

It happens because FriendlyId uses a before_validation callback to set a slug. This method is invoked before any before_validation callbacks that you define in your class.

To fix this you can either invoke friendly_id after you set your before_validation callbacks, or you can just prepend your method before friendly_id:

class User < ActiveRecord::Base
  extend FriendlyId

  friendly_id :login, use: %i( history finders )

  before_validation :set_login
    prepend: true

  def set_login
    # This weird method will just generate a random string
    self.login = (0...8).map { (65 + rand(26)).chr }.join
  end
end

User.new.save!
User.last.login #=> 'bhkcjvrd'
User.last.to_param #=> 'bhkcjvrd'
User.last.slug #=> 'bhkcjvrd'