Лучший способ создания слагов (читабельных идентификаторов) в Rails - PullRequest
61 голосов
/ 19 августа 2009

Вы знаете, как myblog.com/posts/donald-e-knuth.

Должен ли я сделать это с помощью встроенного parameterize метода ?

А как насчет плагина? Я мог бы представить, что плагин хорош для работы с дублирующимися слагами и т. Д. Вот несколько популярных плагинов для Github - кто-нибудь имеет с ними опыт?

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

По сути, похоже, что слизняки - это полностью решенная проблема, и я не изобретаю велосипед.

Ответы [ 12 ]

212 голосов
/ 14 октября 2011

В Rails вы можете использовать # параметризация

Например:

> "Foo bar`s".parameterize 
=> "foo-bar-s"
51 голосов
/ 14 февраля 2010

Лучший способ создания слагов - использовать гем Unidecode . Он имеет самую большую базу данных транслитерации. Он даже транслитерации для китайских иероглифов. Не говоря уже о покрытии всех европейских языков (включая местные диалекты). Это гарантирует создание пуленепробиваемого слизняка.

Например, рассмотрим такие:

"Iñtërnâtiônàlizætiøn".to_slug
=> "internationalizaetion"

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

Я использую его в моей версии метода String.to_slug в моем плагине ruby_extensions . См. ruby_extensions.rb , чтобы узнать о методе to_slug.

36 голосов
/ 19 августа 2009

Я использую следующее, которое будет

  • translate & -> "and" and @ -> "at"
  • не ставит подчеркивание вместо апострофа, поэтому "foo's" -> "foos"
  • не содержит двойных подчеркиваний
  • не создает слаг, который начинается или заканчивается подчеркиванием

  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

так, например:


>> s = "mom & dad @home!"
=> "mom & dad @home!"
>> s.to_slug
> "mom_and_dad_at_home"
9 голосов
/ 19 августа 2009

Вот что я использую:

class User < ActiveRecord::Base
  before_create :make_slug
  private

  def make_slug
    self.slug = self.name.downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')
  end
end

Довольно понятно, хотя единственная проблема в том, что если она уже есть, это не будет name-01 или что-то в этом роде.

Пример:

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

Выходы: -downcase-gsub-a-z1-9-chomp

6 голосов
/ 31 августа 2013

Основной проблемой для моих приложений были апострофы - редко вы хотите, чтобы -s сидели там самостоятельно.

class String

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

end
6 голосов
/ 10 октября 2011

Я немного изменил его, чтобы создать тире вместо подчеркивания, если кому-то интересно:

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
4 голосов
/ 30 апреля 2012

Камень Unidecoder не обновлялся с 2007 года.

Я бы порекомендовал камень stringex, который включает в себя функциональность камня Unidecoder.

https://github.com/rsl/stringex

Глядя на его исходный код, кажется, что он упаковывает исходный код Unidecoder и добавляет новые функциональные возможности.

3 голосов
/ 19 января 2011

Недавно у меня была та же самая дилемма.

Поскольку, как и вы, я не хочу изобретать велосипед, я выбрал friendly_id после сравнения на Ruby Toolbox: Rails Постоянные ссылки и слизни .

Я основал свое решение на:

  • количество наблюдателей github
  • нет. вилок Github
  • когда был сделан последний коммит
  • нет. загрузок

Надеюсь, это поможет принять решение.

3 голосов
/ 19 августа 2009

Мы используем to_slug http://github.com/ludo/to_slug/tree/master. Делает все, что нам нужно для этого (избегая «прикольных персонажей»). Надеюсь, это поможет.

РЕДАКТИРОВАТЬ: Кажется, нарушает мою ссылку, извините за это.

2 голосов
/ 16 февраля 2011

Я обнаружил, что гем Unidecode слишком тяжеловесный, загружая почти 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

Очевидно, вам, вероятно, следует добавить его в качестве метода экземпляра для любых объектов, на которых вы будете его запускать, но для ясности я этого не сделал.

...