Search code examples
ruby-on-railsactiverecordslugalphanumeric

Using alpha-numeric slugs instead of ids in routes - Rails


I am building a Rails 5 team management app which lets users manage organizations and users. I would like to be able to change from using the :id in the path (e.g: /organizations/43) and use an alpha-numeric slug instead (e.g: /organizations/H6Y47Nr7). Similar to how Trello do this (i.e: https://trello.com/b/M9X71pE6/board-name). Is there an easy way of doing this?

I have seen the FriendlyId gem which could take care of the slugging in the path but what would be the best way to generate the slug in the first place?

Ideally, for the most bang for buck the slug would include A-Z, a-z and 0-9 (as I understand it, this is Base58?) and for the sake of not blowing out the url too much, 8 characters at the most. If my calculations are correct, this gives 218 trillion combinations, which should be plenty.

Am I on the right track? Any help would be much appreciated.

Thanks


Solution

  • To create a slug, easiest way is to use SecureRandom. You can add something like the following in your model

    before_create :generate_slug
    
    private
    
    def generate_slug
      begin
        self.slug = SecureRandom.urlsafe_base64(8)
      end while Organization.exists?(slug: slug)
    end
    

    One small caveat here with respect to what you want is that the slug will sometimes contain an underscore or a dash but that should be fine.

    irb(main):014:0> SecureRandom.urlsafe_base64(8)
    => "HlHHV_6rN3k"
    irb(main):015:0> SecureRandom.urlsafe_base64(8)
    => "naRqT-NmYDU"
    irb(main):016:0> SecureRandom.urlsafe_base64(8)
    => "9h04l4jEEsM"