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


вы знаете, как 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 59

12 ответов:

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

  • перевести & --> "и" и @ -- > "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"

в Rails вы можете использовать #parameterize

например:

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

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

рассмотрим, например, эти:

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

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

Я использую его в моей версии метода String. to_slug в моем плагин ruby_extensions. Видеть ruby_extensions.РБ для метода to_slug.

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

class User < ActiveRecord::Base
  before_create :make_slug
  private

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

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

пример:

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

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

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

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

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

class String

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

end

unidecoder gem не обновлялся с 2007 года.

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

https://github.com/rsl/stringex

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

мы используем:to_slughttp://github.com/ludo/to_slug/tree/master. Делает все, что нам нужно, чтобы сделать (избегая "фанки символов"). Надеюсь, это поможет.

EDIT: кажется, ломает мою ссылку, извините за это.

У меня была такая же дилемма.

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

я основывал свое решение на:

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

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

я обнаружил, что 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

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

С Rails 3, я создал инициализатор, slug.rb, в который я ввел следующий код:

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

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

транслитерат преобразует такие вещи,как é,á, " в e,a, o. поскольку я разрабатываю сайт на португальском языке, это имеет значение.

Я знаю, что этот вопрос имеет некоторое время сейчас. Однако я вижу некоторые относительно новые ответы.

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

Я написал сообщение после этого рассуждения,и надеюсь, что это поможет.

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