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
Best way to generate slugs (human-readable IDs) in Rails
提问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?
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 插件——有人对它们有任何经验吗?
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
回答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.
显然,您应该将它作为实例方法添加到您将运行它的任何对象上,但为了清楚起见,我没有。

