Best way to generate slugs (human-readable IDs) in Rails

前端 未结 12 822
北荒
北荒 2020-11-30 18:05

You know, like myblog.com/posts/donald-e-knuth.

Should I do this with the built in parameterize method?

What about a plugin? I could imagine a plugin being n

相关标签:
12条回答
  • 2020-11-30 19:03

    I know this question has some time now. However I see some relatively new answers.

    Saving the slug on the database is problematic, and you save redundant information that is already there. If you think about it, there is no reason for saving the slug. The slug should be logic, not data.

    I wrote a post following this reasoning, and hope is of some help.

    http://blog.ereslibre.es/?p=343

    0 讨论(0)
  • 2020-11-30 19:04

    Here is what I use:

    class User < ActiveRecord::Base
      before_create :make_slug
      private
    
      def make_slug
        self.slug = self.name.downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')
      end
    end
    

    Pretty self explanatory, although the only problem with this is if there is already the same one, it won't be name-01 or something like that.

    Example:

    ".downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')".downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')
    

    Outputs: -downcase-gsub-a-z1-9-chomp

    0 讨论(0)
  • 2020-11-30 19:04

    I found the Unidecode gem to be much too heavyweight, loading nearly 200 YAML files, for what I needed. I knew iconv had some support for the basic translations, and while it isn't perfect, it's built in and fairly lightweight. This is what I came up with:

    require 'iconv' # unless you're in Rails or already have it loaded
    def slugify(text)
      text.downcase!
      text = Iconv.conv('ASCII//TRANSLIT//IGNORE', 'UTF8', text)
    
      # Replace whitespace characters with hyphens, avoiding duplication
      text.gsub! /\s+/, '-'
    
      # Remove anything that isn't alphanumeric or a hyphen
      text.gsub! /[^a-z0-9-]+/, ''
    
      # Chomp trailing hyphens
      text.chomp '-'
    end
    

    Obviously you should probably add it as an instance method on any objects you'll be running it on, but for clarity, I didn't.

    0 讨论(0)
  • 2020-11-30 19:05

    The Unidecoder gem hasn't been updated since 2007.

    I'd recommend the stringex gem, which includes the functionality of the Unidecoder gem.

    https://github.com/rsl/stringex

    Looking at it's source code, it seems to repackage the Unidecoder source code and add new functionality.

    0 讨论(0)
  • 2020-11-30 19:06

    I use the following, which will

    • translate & --> "and" and @ --> "at"
    • doesn't insert an underscore in place of an apostrophe, so "foo's" --> "foos"
    • doesn't include double-underscores
    • doesn't create slug that begins or ends with an underscore
    
      def to_slug
        #strip the string
        ret = self.strip
    
        #blow away apostrophes
        ret.gsub! /['`]/,""
    
        # @ --> at, and & --> and
        ret.gsub! /\s*@\s*/, " at "
        ret.gsub! /\s*&\s*/, " and "
    
        #replace all non alphanumeric, underscore or periods with underscore
         ret.gsub! /\s*[^A-Za-z0-9\.\-]\s*/, '_'  
    
         #convert double underscores to single
         ret.gsub! /_+/,"_"
    
         #strip off leading/trailing underscore
         ret.gsub! /\A[_\.]+|[_\.]+\z/,""
    
         ret
      end
    

    so, for example:

    
    >> s = "mom & dad @home!"
    => "mom & dad @home!"
    >> s.to_slug
    > "mom_and_dad_at_home"
    
    0 讨论(0)
  • 2020-11-30 19:06

    We use to_slug http://github.com/ludo/to_slug/tree/master. Does everything we need it to do (escaping 'funky characters'). Hope this helps.

    EDIT: Seems to be breaking my link, sorry about that.

    0 讨论(0)
提交回复
热议问题