Spec-Zone.ru › Ruby on Rails 5.1

модуль ActiveSupport::Inflector

Класс Inflector преобразует слова от единственного к множественному числу, имена классов в имена таблиц, имена модульных классов в имена без модулей и имена классов в внешние ключи. Стандартные склонения для множественного, единственного числа и несчётных слов хранятся в inflections.rb.

Команда разработчиков Rails заявила, что исправления для библиотеки склонений не принимаются, чтобы избежать разрыва совместимости с устаревшими приложениями, которые могут полагаться на неправильные склонения. Если вы обнаружите неверное склонение, необходимое для вашего приложения, или захотите определить правила для языков помимо английского, пожалуйста, исправьте или добавьте их самостоятельно (объяснено ниже).

Методы публичного экземпляра

camelize(term, uppercase_first_letter = true) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 67
def camelize(term, uppercase_first_letter = true)
  string = term.to_s
  if uppercase_first_letter
    string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize }
  else
    string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { |match| match.downcase }
  end
  string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
  string.gsub!("/".freeze, "::".freeze)
  string
end

Преобразует строки в UpperCamelCase. Если параметр uppercase_first_letter установлен в false, то генерируется lowerCamelCase.

Также преобразует '/' в '::', что полезно для преобразования путей в пространства имён.

camelize('active_model')                # => "ActiveModel"
camelize('active_model', false)         # => "activeModel"
camelize('active_model/errors')         # => "ActiveModel::Errors"
camelize('active_model/errors', false)  # => "activeModel::Errors"

Как правило, можно считать, что camelize является обратным методом underscore, хотя есть случаи, когда это не так:

camelize(underscore('SSLError'))        # => "SslError"
classify(table_name) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 187
def classify(table_name)
  # strip out any leading schema name
  camelize(singularize(table_name.to_s.sub(/.*\./, "".freeze)))
end

Создаёт имя класса из имени таблицы, как это делает Rails для имён таблиц моделей. Обратите внимание, что это возвращает строку, а не Класс (для преобразования в фактический класс выполните classify с constantize).

classify('ham_and_eggs') # => "HamAndEgg"
classify('posts')        # => "Post"

Имена единственного числа обрабатываются некорректно:

classify('calculus')     # => "Calculus"
constantize(camel_cased_word) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 258
def constantize(camel_cased_word)
  names = camel_cased_word.split("::".freeze)

  # Trigger a built-in NameError exception including the ill-formed constant in the message.
  Object.const_get(camel_cased_word) if names.empty?

  # Remove the first blank element in case of '::ClassName' notation.
  names.shift if names.size > 1 && names.first.empty?

  names.inject(Object) do |constant, name|
    if constant == Object
      constant.const_get(name)
    else
      candidate = constant.const_get(name)
      next candidate if constant.const_defined?(name, false)
      next candidate unless Object.const_defined?(name)

      # Go down the ancestors to check if it is owned directly. The check
      # stops when we reach Object or the end of ancestors tree.
      constant = constant.ancestors.inject(constant) do |const, ancestor|
        break const    if ancestor == Object
        break ancestor if ancestor.const_defined?(name, false)
        const
      end

      # owner is in Object, so raise
      constant.const_get(name, false)
    end
  end
end

Попытка найти константу с именем, указанным в строке аргумента.

constantize('Module')   # => Module
constantize('Foo::Bar') # => Foo::Bar

Имя предполагается как имя константы верхнего уровня, независимо от того, начинается ли оно с «::» или нет. Не учитывается лексический контекст:

C = 'outside'
module M
  C = 'inside'
  C                # => 'inside'
  constantize('C') # => 'outside', same as ::C
end

NameError генерируется, если имя не в CamelCase или константа неизвестна.

dasherize(underscored_word) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 195
def dasherize(underscored_word)
  underscored_word.tr("_".freeze, "-".freeze)
end

Заменяет подчёркивания дефисами в строке.

dasherize('puni_puni') # => "puni-puni"
deconstantize(path) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 225
def deconstantize(path)
  path.to_s[0, path.rindex("::") || 0] # implementation based on the one in facets' Module#spacename
end

Удаляет самый правый сегмент из выражения константы в строке.

deconstantize('Net::HTTP')   # => "Net"
deconstantize('::Net::HTTP') # => "::Net"
deconstantize('String')      # => ""
deconstantize('::String')    # => ""
deconstantize('')            # => ""

См. также demodulize.

demodulize(path) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 207
def demodulize(path)
  path = path.to_s
  if i = path.rindex("::")
    path[(i + 2)..-1]
  else
    path
  end
end

Удаляет модульную часть из выражения в строке.

demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections"
demodulize('Inflections')                           # => "Inflections"
demodulize('::Inflections')                         # => "Inflections"
demodulize('')                                      # => ""

См. также deconstantize.

foreign_key(class_name, separate_class_name_and_id_with_underscore = true) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 236
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
  underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
end

Создаёт имя внешнего ключа из имени класса. separate_class_name_and_id_with_underscore устанавливает, нужно ли вставлять '_' между именем и 'id'.

foreign_key('Message')        # => "message_id"
foreign_key('Message', false) # => "messageid"
foreign_key('Admin::Post')    # => "post_id"
humanize(lower_case_and_underscored_word, options = {}) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 124
def humanize(lower_case_and_underscored_word, options = {})
  result = lower_case_and_underscored_word.to_s.dup

  inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }

  result.sub!(/\A_+/, "".freeze)
  result.sub!(/_id\z/, "".freeze)
  result.tr!("_".freeze, " ".freeze)

  result.gsub!(/([a-z\d]*)/i) do |match|
    "#{inflections.acronyms[match] || match.downcase}"
  end

  if options.fetch(:capitalize, true)
    result.sub!(/\A\w/) { |match| match.upcase }
  end

  result
end

Настраивает имя атрибута для отображения пользователям.

В частности, выполняет следующие преобразования:

  • Применяет правила человеческой инфлексии к аргументу.

  • Удаляет ведущие подчёркивания, если они есть.

  • Удаляет суффикс «_id», если он присутствует.

  • Заменяет подчёркивания пробелами, если они есть.

  • Преобразует все слова в нижний регистр, за исключением аббревиатур.

  • Преобразует первое слово в верхний регистр.

Заглавность первого слова можно отключить, установив опцию :capitalize в false (по умолчанию true).

humanize('employee_salary')              # => "Employee salary"
humanize('author_id')                    # => "Author"
humanize('author_id', capitalize: false) # => "author"
humanize('_id')                          # => "Id"

Если «SSL» определено как аббревиатура:

humanize('ssl_error') # => "SSL error"
inflections(locale = :en) { |instance| ... } Показать исходный код
# File activesupport/lib/active_support/inflector/inflections.rb, line 236
def inflections(locale = :en)
  if block_given?
    yield Inflections.instance(locale)
  else
    Inflections.instance(locale)
  end
end

Возвращает синглтон экземпляр Inflector::Inflections, чтобы вы могли указать дополнительные правила инфлектора. Если передан необязательный locale, правила для других языков могут быть указаны. Если не указано, по умолчанию :en. Предоставляются только правила для английского языка.

ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.uncountable 'rails'
end
ordinal(number) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 329
def ordinal(number)
  abs_number = number.to_i.abs

  if (11..13).include?(abs_number % 100)
    "th"
  else
    case abs_number % 10
    when 1; "st"
    when 2; "nd"
    when 3; "rd"
      else    "th"
    end
  end
end

Возвращает суффикс, который следует добавить к числу, чтобы обозначить позицию в упорядоченной последовательности, например, 1-е, 2-е, 3-е, 4-е.

ordinal(1)     # => "st"
ordinal(2)     # => "nd"
ordinal(1002)  # => "nd"
ordinal(1003)  # => "rd"
ordinal(-11)   # => "th"
ordinal(-1021) # => "st"
ordinalize(number) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 353
def ordinalize(number)
  "#{number}#{ordinal(number)}"
end

Преобразует число в строку порядкового числительного, используемую для обозначения позиции в упорядоченной последовательности, например, 1-е, 2-е, 3-е, 4-е.

ordinalize(1)     # => "1st"
ordinalize(2)     # => "2nd"
ordinalize(1002)  # => "1002nd"
ordinalize(1003)  # => "1003rd"
ordinalize(-11)   # => "-11th"
ordinalize(-1021) # => "-1021st"
parameterize(string, separator: "-", preserve_case: false) Показать исходный код
# File activesupport/lib/active_support/inflector/transliterate.rb, line 83
def parameterize(string, separator: "-", preserve_case: false)
  # Replace accented chars with their ASCII equivalents.
  parameterized_string = transliterate(string)

  # Turn unwanted chars into the separator.
  parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)

  unless separator.nil? || separator.empty?
    if separator == "-".freeze
      re_duplicate_separator        = /-{2,}/
      re_leading_trailing_separator = /^-|-$/i
    else
      re_sep = Regexp.escape(separator)
      re_duplicate_separator        = /#{re_sep}{2,}/
      re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/i
    end
    # No more than one of the separator in a row.
    parameterized_string.gsub!(re_duplicate_separator, separator)
    # Remove leading/trailing separator.
    parameterized_string.gsub!(re_leading_trailing_separator, "".freeze)
  end

  parameterized_string.downcase! unless preserve_case
  parameterized_string
end

Заменяет специальные символы в строке, чтобы её можно было использовать в качестве части «красивого» URL.

parameterize("Donald E. Knuth") # => "donald-e-knuth"
parameterize("^trés|Jolie-- ")  # => "tres-jolie"

Для использования пользовательского разделителя переопределите аргумент `separator`.

parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
parameterize("^trés|Jolie-- ", separator: '_')  # => "tres_jolie"

Чтобы сохранить регистр символов в строке, используйте аргумент `preserve_case`.

parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
parameterize("^trés|Jolie-- ", preserve_case: true) # => "tres-Jolie"
pluralize(word, locale = :en) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 30
def pluralize(word, locale = :en)
  apply_inflections(word, inflections(locale).plurals)
end

Возвращает множественное число слова в строке.

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

pluralize('post')             # => "posts"
pluralize('octopus')          # => "octopi"
pluralize('sheep')            # => "sheep"
pluralize('words')            # => "words"
pluralize('CamelOctopus')     # => "CamelOctopi"
pluralize('ley', :es)         # => "leyes"
safe_constantize(camel_cased_word) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 311
def safe_constantize(camel_cased_word)
  constantize(camel_cased_word)
rescue NameError => e
  raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) ||
    e.name.to_s == camel_cased_word.to_s)
rescue ArgumentError => e
  raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message)
end

Попытка найти константу с именем, указанным в строке аргумента.

safe_constantize('Module')   # => Module
safe_constantize('Foo::Bar') # => Foo::Bar

Имя предполагается как имя константы верхнего уровня, независимо от того, начинается ли оно с «::» или нет. Не учитывается лексический контекст:

C = 'outside'
module M
  C = 'inside'
  C                     # => 'inside'
  safe_constantize('C') # => 'outside', same as ::C
end

Возвращается nil, если имя не в CamelCase или константа (или её часть) неизвестна.

safe_constantize('blargle')                  # => nil
safe_constantize('UnknownModule')            # => nil
safe_constantize('UnknownModule::Foo::Bar')  # => nil
singularize(word, locale = :en) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 47
def singularize(word, locale = :en)
  apply_inflections(word, inflections(locale).singulars)
end

Обратная функция pluralize, возвращает единственное число слова в строке.

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

singularize('posts')            # => "post"
singularize('octopi')           # => "octopus"
singularize('sheep')            # => "sheep"
singularize('word')             # => "word"
singularize('CamelOctopi')      # => "CamelOctopus"
singularize('leyes', :es)       # => "ley"
tableize(class_name) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 173
def tableize(class_name)
  pluralize(underscore(class_name))
end

Создаёт имя таблицы, как это делает Rails для имён моделей в имена таблиц. Этот метод использует метод pluralize для последнего слова в строке.

tableize('RawScaledScorer') # => "raw_scaled_scorers"
tableize('ham_and_egg')     # => "ham_and_eggs"
tableize('fancyCategory')   # => "fancy_categories"
titleize(word) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 163
def titleize(word)
  humanize(underscore(word)).gsub(/\b(?<!\w['’`])[a-z]/) { |match| match.capitalize }
end

Преобразует все слова в заглавные и заменяет некоторые символы в строке, чтобы создать более красивый заголовок. titleize предназначен для создания красивого вывода. Он не используется в внутренних компонентах Rails.

titleize также алиасирован как titlecase.

titleize('man from the boondocks')   # => "Man From The Boondocks"
titleize('x-men: the last stand')    # => "X Men: The Last Stand"
titleize('TheManWithoutAPast')       # => "The Man Without A Past"
titleize('raiders_of_the_lost_ark')  # => "Raiders Of The Lost Ark"
END_OF_DOCUMENT_MARKER
transliterate(string, replacement = "?".freeze) Показать исходный код
# File activesupport/lib/active_support/inflector/transliterate.rb, line 59
def transliterate(string, replacement = "?".freeze)
  raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)

  I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
    ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
      replacement: replacement)
end

Заменяет не-ASCII символы на их приближённые ASCII аналоги, или, если такого аналога нет, на символ-заполнитель, по умолчанию равный “?”.

transliterate('Ærøskøbing')
# => "AEroskobing"

Для западных/латинских символов предоставляются приближения, например, “ø”, “ñ”, “é”, “ß” и т.д.

Этот метод учитывает I18n, поэтому вы можете настроить пользовательские приближения для конкретного региона. Это может быть полезно, например, для транслитерации немецких “ü” и “ö” в “ue” и “oe” или для добавления поддержки транслитерации русского языка в ASCII.

Для того, чтобы ваши пользовательские транслитерации стали доступны, вы должны установить их как i18n.transliterate.rule ключ i18n:

# Store the transliterations in locales/de.yml
i18n:
  transliterate:
    rule:
      ü: "ue"
      ö: "oe"

# Or set them using Ruby
I18n.backend.store_translations(:de, i18n: {
  transliterate: {
    rule: {
      'ü' => 'ue',
      'ö' => 'oe'
    }
  }
})

Значение для i18n.transliterate.rule может быть простым словарём, сопоставляющим символы с их ASCII приближениями, как показано выше, или, для более сложных требований, функцией:

I18n.backend.store_translations(:de, i18n: {
  transliterate: {
    rule: ->(string) { MyTransliterator.transliterate(string) }
  }
})

Теперь вы можете иметь различные транслитерации для каждого региона:

I18n.locale = :en
transliterate('Jürgen')
# => "Jurgen"

I18n.locale = :de
transliterate('Jürgen')
# => "Juergen"
underscore(camel_cased_word) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 90
def underscore(camel_cased_word)
  return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
  word = camel_cased_word.to_s.gsub("::".freeze, "/".freeze)
  word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'.freeze }#{$2.downcase}" }
  word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
  word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
  word.tr!("-".freeze, "_".freeze)
  word.downcase!
  word
end

Преобразует выражение в строке в нижний регистр с подчеркиванием.

Заменяет '::' на '/' для преобразования пространств имён в пути.

underscore('ActiveModel')         # => "active_model"
underscore('ActiveModel::Errors') # => "active_model/errors"

Как правило, можно считать, что underscore является обратным camelize, хотя существуют случаи, когда это не так:

camelize(underscore('SSLError'))  # => "SslError"
upcase_first(string) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 149
def upcase_first(string)
  string.length > 0 ? string[0].upcase.concat(string[1..-1]) : ""
end

Преобразует только первый символ в верхний регистр.

upcase_first('what a Lovely Day') # => "What a Lovely Day"
upcase_first('w')                 # => "W"
upcase_first('')                  # => ""

© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API