在Rails中生成蛞蝓(人类可读的id)的最佳方式

时间:2022-11-24 20:44:14

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

你知道,像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 nice for handling duplicate slugs, etc. Here are some popular Github plugins -- does anyone have any experience with them?

一个插件呢?我可以想象一个插件可以很好地处理重复的蛞蝓,等等。这里有一些流行的Github插件——有人有使用它们的经验吗?

  1. http://github.com/rsl/stringex/tree/master
  2. http://github.com/rsl/stringex/tree/master
  3. http://github.com/norman/friendly_id/tree/master
  4. 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.

基本上来说,鼻涕虫是一个完全解决了的问题,我不会重新发明*。

12 个解决方案

#1


36  

I use the following, which will

我用下面的,它会

  • translate & --> "and" and @ --> "at"
  • 翻译& ->和@ -> "at"
  • doesn't insert an underscore in place of an apostrophe, so "foo's" --> "foos"
  • 不插入一个下划线代替撇号,所以是"foo " -> "foos"
  • doesn't include double-underscores
  • 不包括双下划线
  • doesn't create slug that begins or ends with an underscore
  • 不创建以下划线开头或结尾的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"

#2


204  

In Rails you can use #parameterize

在Rails中,可以使用#parameterize

For example:

例如:

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

#3


50  

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.

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

For example, consider those:

例如,考虑这些:

"Iñtërnâtiô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.rb for the to_slug method.

我在我的字符串版本中使用它。我的ruby_extensions插件中的to_slug方法。看到ruby_extensions。to_slug方法的rb。

#4


8  

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

#5


6  

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

#6


5  

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

#7


4  

The Unidecoder gem hasn't been updated since 2007.

自2007年以来,Unidecoder gem还没有进行过更新。

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源代码并添加了新的功能。

#8


3  

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.

我们使用to_slug http://github.com/ludo/to_slug/tree/master。我们需要它做的每件事都做了吗?希望这个有帮助。

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

编辑:看来我的链接坏了,抱歉。

#9


3  

Recently I had the same dilemma.

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

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

因为和你一样,我也不想重新发明*,所以我选择了friendly_id,这是根据Ruby工具箱中的比较:Rails Permalinks和Slugs。

I based my decision on:

我的决定基于:

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

Hope this helps in taking the decision.

希望这有助于我们做出决定。

#10


2  

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:

我发现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.

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

#11


0  

With Rails 3, I've created an initializer, slug.rb, in which I've put the following code:

使用Rails 3,我创建了一个初始化器,slug。rb,我在里面放了如下代码:

class String
  def to_slug
    ActiveSupport::Inflector.transliterate(self.downcase).gsub(/[^a-zA-Z0-9]+/, '-').gsub(/-{2,}/, '-').gsub(/^-|-$/, '')
  end
end

Then I use it anywhere I want in the code, it is defined for any string.

然后我在代码中任意使用它,它是为任何字符串定义的。

The transliterate transforms things like é,á,ô into e,a,o. As I am developing a site in portuguese, that matters.

音译将e a o转换成e a o。因为我正在开发一个葡萄牙语的网站,这很重要。

#12


-2  

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

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

#1


36  

I use the following, which will

我用下面的,它会

  • translate & --> "and" and @ --> "at"
  • 翻译& ->和@ -> "at"
  • doesn't insert an underscore in place of an apostrophe, so "foo's" --> "foos"
  • 不插入一个下划线代替撇号,所以是"foo " -> "foos"
  • doesn't include double-underscores
  • 不包括双下划线
  • doesn't create slug that begins or ends with an underscore
  • 不创建以下划线开头或结尾的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"

#2


204  

In Rails you can use #parameterize

在Rails中,可以使用#parameterize

For example:

例如:

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

#3


50  

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.

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

For example, consider those:

例如,考虑这些:

"Iñtërnâtiô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.rb for the to_slug method.

我在我的字符串版本中使用它。我的ruby_extensions插件中的to_slug方法。看到ruby_extensions。to_slug方法的rb。

#4


8  

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

#5


6  

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

#6


5  

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

#7


4  

The Unidecoder gem hasn't been updated since 2007.

自2007年以来,Unidecoder gem还没有进行过更新。

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源代码并添加了新的功能。

#8


3  

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.

我们使用to_slug http://github.com/ludo/to_slug/tree/master。我们需要它做的每件事都做了吗?希望这个有帮助。

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

编辑:看来我的链接坏了,抱歉。

#9


3  

Recently I had the same dilemma.

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

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

因为和你一样,我也不想重新发明*,所以我选择了friendly_id,这是根据Ruby工具箱中的比较:Rails Permalinks和Slugs。

I based my decision on:

我的决定基于:

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

Hope this helps in taking the decision.

希望这有助于我们做出决定。

#10


2  

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:

我发现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.

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

#11


0  

With Rails 3, I've created an initializer, slug.rb, in which I've put the following code:

使用Rails 3,我创建了一个初始化器,slug。rb,我在里面放了如下代码:

class String
  def to_slug
    ActiveSupport::Inflector.transliterate(self.downcase).gsub(/[^a-zA-Z0-9]+/, '-').gsub(/-{2,}/, '-').gsub(/^-|-$/, '')
  end
end

Then I use it anywhere I want in the code, it is defined for any string.

然后我在代码中任意使用它,它是为任何字符串定义的。

The transliterate transforms things like é,á,ô into e,a,o. As I am developing a site in portuguese, that matters.

音译将e a o转换成e a o。因为我正在开发一个葡萄牙语的网站,这很重要。

#12


-2  

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

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