Лучший способ для генерации слизней (человеко-понятных идентификаторов) в Rails
вы знаете, как myblog.com/posts/donald-e-knuth.
должен ли я сделать это со встроенным parameterize
способ?
Как насчет плагинов? Я мог бы представить себе плагин, который хорош для обработки дубликатов слизней и т. д. Вот некоторые популярные плагины Github - есть ли у кого-нибудь опыт работы их?
в основном кажется, что слизни-это полностью решенная проблема, и я не изобретаю колесо.
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_slug
http://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. поскольку я разрабатываю сайт на португальском языке, это имеет значение.
Я знаю, что этот вопрос имеет некоторое время сейчас. Однако я вижу некоторые относительно новые ответы.
сохранение пули в базе данных является проблематичным, и вы сохраняете избыточную информацию, которая уже есть. Если вы подумаете об этом, нет никаких причин для спасения слизняка. Пуля должна быть логикой, а не данными.
Я написал сообщение после этого рассуждения,и надеюсь, что это поможет.