Spec-Zone.ru › Ruby on Rails 4.2

модуль 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]*/) { inflections.acronyms[$&] || $&.capitalize }
  else
    string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
  end
  string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
  string.gsub!(/\//, '::')
  string
end

По умолчанию, camelize преобразует строки в UpperCamelCase. Если аргумент к camelize установлен в :lower, то camelize создаёт lowerCamelCase.

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

'active_model'.camelize                # => "ActiveModel"
'active_model'.camelize(:lower)        # => "activeModel"
'active_model/errors'.camelize         # => "ActiveModel::Errors"
'active_model/errors'.camelize(:lower) # => "activeModel::Errors"

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

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

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

'egg_and_hams'.classify # => "EggAndHam"
'posts'.classify        # => "Post"

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

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

  # 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 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

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

'Module'.constantize     # => Module
'Test::Unit'.constantize # => Test::Unit

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

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

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

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

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

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

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

'Net::HTTP'.deconstantize   # => "Net"
'::Net::HTTP'.deconstantize # => "::Net"
'String'.deconstantize      # => ""
'::String'.deconstantize    # => ""
''.deconstantize            # => ""

См. также demodulize.

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

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

'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
'Inflections'.demodulize                                       # => "Inflections"
'::Inflections'.demodulize                                     # => "Inflections"
''.demodulize                                                  # => ""

См. также deconstantize.

foreign_key(class_name, separate_class_name_and_id_with_underscore = true) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 227
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'.

'Message'.foreign_key        # => "message_id"
'Message'.foreign_key(false) # => "messageid"
'Admin::Post'.foreign_key    # => "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_+/, '')
  result.sub!(/_id\z/, '')
  result.tr!('_', ' ')

  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

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

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

* Applies human inflection rules to the argument.
* Deletes leading underscores, if any.
* Removes a "_id" suffix if present.
* Replaces underscores with spaces, if any.
* Downcases all words except acronyms.
* Capitalizes the first word.

Регистр первой буквы слова можно отключить, установив параметр :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 203
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 320
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 344
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, sep = '-') Показать исходный код
# File activesupport/lib/active_support/inflector/transliterate.rb, line 80
def parameterize(string, sep = '-')
  # replace accented chars with their ascii equivalents
  parameterized_string = transliterate(string)
  # Turn unwanted chars into the separator
  parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep)
  unless sep.nil? || sep.empty?
    re_sep = Regexp.escape(sep)
    # No more than one of the separator in a row.
    parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
    # Remove leading/trailing separator.
    parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
  end
  parameterized_string.downcase
end

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

class Person
  def to_param
    "#{id}-#{name.parameterize}"
  end
end

@person = Person.find(1)
# => #<Person id: 1, name: "Donald E. Knuth">

<%= link_to(@person.name, person_path(@person)) %>
# => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
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.

'post'.pluralize             # => "posts"
'octopus'.pluralize          # => "octopi"
'sheep'.pluralize            # => "sheep"
'words'.pluralize            # => "words"
'CamelOctopus'.pluralize     # => "CamelOctopi"
'ley'.pluralize(:es)         # => "leyes"
safe_constantize(camel_cased_word) Показать исходный код
# File activesupport/lib/active_support/inflector/methods.rb, line 302
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 e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
end

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

'Module'.safe_constantize     # => Module
'Test::Unit'.safe_constantize # => Test::Unit

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

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

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

'blargle'.safe_constantize  # => nil
'UnknownModule'.safe_constantize  # => nil
'UnknownModule::Foo::Bar'.safe_constantize  # => 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.

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

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

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

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

titleize также проименован как titlecase.

'man from the boondocks'.titleize   # => "Man From The Boondocks"
'x-men: the last stand'.titleize    # => "X Men: The Last Stand"
'TheManWithoutAPast'.titleize       # => "The Man Without A Past"
'raiders_of_the_lost_ark'.titleize  # => "Raiders Of The Lost Ark"
END_OF_DOCUMENT_MARKER
transliterate(string, replacement = "?") Показать исходный код
# File activesupport/lib/active_support/inflector/transliterate.rb, line 60
def transliterate(string, replacement = "?")
  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 может быть простым Hash, который сопоставляет символы с их приближениями в ASCII, как показано выше, или, для более сложных требований, объектом Proc:

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 camel_cased_word =~ /[A-Z-]|::/
  word = camel_cased_word.to_s.gsub(/::/, '/')
  word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'}#{$2.downcase}" }
  word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
  word.tr!("-", "_")
  word.downcase!
  word
end

Создаёт подчёркнутую, строчную форму из выражения в строке.

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

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

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

'SSLError'.underscore.camelize # => "SslError"

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

Spec-Zone.ru

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