Ruby-on-rails 在 Rails 中生成 slugs(人类可读的 ID)的最佳方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1302022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:38:35  来源:igfitidea点击:

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

ruby-on-railsslug

提问by Tom Lehman

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

你知道,比如 myblog.com/posts/donald-e-knuth。

Should I do this with the built in parameterizemethod?

我应该使用内置parameterize方法执行此操作吗?

What about a plugin? I could imagine a plugin being nice for handling duplicate slugs, etc. Here are some popular Github plugins -- does anyone have any experience with them?

插件呢?我可以想象一个插件可以很好地处理重复的 slug 等。这里有一些流行的 Github 插件——有人对它们有任何经验吗?

  1. http://github.com/rsl/stringex/tree/master
  2. http://github.com/norman/friendly_id/tree/master
  1. http://github.com/rsl/stringex/tree/master
  2. http://github.com/norman/friendly_id/tree/master

Basically it seems like slugs are a totally solved problem, and I don't to reinvent the wheel.

基本上,slugs 似乎是一个完全解决的问题,我不想重新发明轮子。

采纳答案by klochner

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
  • 翻译 & --> "and" 和 @ --> "at"
  • 不插入下划线代替撇号,所以 "foo's" --> "foos"
  • 不包括双下划线
  • 不会创建以下划线开头或结尾的 slug

  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"

回答by grosser

In Rails you can use #parameterize

在 Rails 中,您可以使用#parameterize

For example:

例如:

> "Foo bar`s".parameterize 
=> "foo-bar-s"

回答by Pawe? Go?cicki

The best way to generate slugs is to use the Unidecode gem. It has by far the largest transliteration database available. It has even transliterations for Chinese characters. Not to mention covering all European languages (including local dialects). It guarantees a bulletproof slug creation.

生成 slug 的最佳方法是使用Unidecode gem。它拥有迄今为止最大的音译数据库。它甚至有汉字的音译。更不用说涵盖所有欧洲语言(包括当地方言)。它保证了防弹弹头的产生。

For example, consider those:

例如,考虑那些:

"I?t?rnati?nàliz?ti?n".to_slug
=> "internationalizaetion"

>> "中文測試".to_slug
=> "zhong-wen-ce-shi"

I use it in my version of the String.to_slug method in my ruby_extensions plugin. See ruby_extensions.rbfor the to_slug method.

我在我的ruby_extensions 插件中的 String.to_slug 方法版本中使用它。有关to_slug 方法,请参见ruby_extensions.rb

回答by Garrett

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.

不言自明,虽然唯一的问题是如果已经有相同的,它不会是 name-01 或类似的东西。

Example:

例子:

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

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

输出: -downcase-gsub-a-z1-9-chomp

回答by Victor S

I modified it a bit to create dashes instead of underscores, if anyone is interested:

如果有人感兴趣,我对其进行了一些修改以创建破折号而不是下划线:

def to_slug(param=self.slug)

    # strip the string
    ret = param.strip

    #blow away apostrophes
    ret.gsub! /['`]/, ""

    # @ --> at, and & --> and
    ret.gsub! /\s*@\s*/, " at "
    ret.gsub! /\s*&\s*/, " and "

    # replace all non alphanumeric, periods with dash
    ret.gsub! /\s*[^A-Za-z0-9\.]\s*/, '-'

    # replace underscore with dash
    ret.gsub! /[-_]{2,}/, '-'

    # convert double dashes to single
    ret.gsub! /-+/, "-"

    # strip off leading/trailing dash
    ret.gsub! /\A[-\.]+|[-\.]+\z/, ""

    ret
  end

回答by Mark Swardstrom

The main issue for my apps has been the apostrophes - rarely do you want the -s sitting out there on it's own.

我的应用程序的主要问题是撇号 - 您很少希望 -s 单独存在。

class String

  def to_slug
    self.gsub(/['`]/, "").parameterize
  end

end

回答by Tilo

The Unidecoder gem hasn't been updated since 2007.

Unidecoder gem 自 2007 年以来就没有更新过。

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

我推荐 stringex gem,它包含 Unidecoder gem 的功能。

https://github.com/rsl/stringex

https://github.com/rsl/stringex

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

查看它的源代码,它似乎重新打包了 Unidecoder 源代码并添加了新功能。

回答by Marius Butuc

Recently I had the same dilemma.

最近我也遇到了同样的困境。

Since, like you, I don't want to reinvent the wheel, I chose friendly_idfollowing the comparison on The Ruby Toolbox: Rails Permalinks & Slugs.

因为和你一样,我不想重新发明轮子,所以我在The Ruby Toolbox: Rails Permalinks & Slugs上的比较之后选择了friendly_id

I based my decision on:

我的决定基于:

  • number of github watchers
  • no. of github forks
  • when was the last commit made
  • no. of downloads
  • github 观察者的数量
  • 不。github分叉
  • 最后一次提交是什么时候
  • 不。下载量

Hope this helps in taking the decision.

希望这有助于做出决定。

回答by theIV

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

我们使用to_slughttp://github.com/ludo/to_slug/tree/master。做我们需要它做的一切(逃避“时髦的角色”)。希望这可以帮助。

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

编辑:似乎打破了我的链接,对此感到抱歉。

回答by coreyward

I found the Unidecode gem to be much too heavyweight, loading nearly 200 YAML files, for what I needed. I knew iconvhad 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:

我发现 Unidecode gem 太重了,加载了近 200 个 YAML 文件,满足我的需要。我知道iconv对基本翻译有一些支持,虽然它并不完美,但它是内置的并且相当轻量级。这就是我想出的:

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.

显然,您应该将它作为实例方法添加到您将运行它的任何对象上,但为了清楚起见,我没有。