Module: Inflecto

Defined in:
lib/inflecto.rb,
lib/inflecto/inflections.rb

Overview

The Inflecto transforms words from singular to plural, class names to table names, modularized class names to ones without, and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept in inflections.rb.

The Rails core team has stated patches for the inflections library will not be accepted in order to avoid breaking legacy applications which may be relying on errant inflections. If you discover an incorrect inflection and require it for your application, you’ll need to correct it yourself (explained below).

Defined Under Namespace

Classes: Inflections

Class Method Summary collapse

Class Method Details

.camelize(input) ⇒ String

Convert input to UpperCamelCase

Will also convert ‘/’ to ‘::’ which is useful for converting paths to namespaces.

Examples:

Inflecto.camelize("data_mapper")        # => "DataMapper"
Inflecto.camelize("data_mapper/errors") # => "DataMApper::Errors"

Parameters:

  • input (String)

Returns:

  • (String)


25
26
27
# File 'lib/inflecto.rb', line 25

def self.camelize(input)
  input.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
end

.classify(table_name) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Classify input

Create a class name from a plural table name like Rails does for table names to models. Note that this returns a string and not a Class.

To convert to an actual class # follow classify with constantize.

@examples:

Inflecto.classify("egg_and_hams") # => "EggAndHam"
Inflecto.classify("posts")        # => "Post"

# Singular names are not handled correctly:
Inflecto.classify("business")     # => "Busines"

Returns:

  • (String)


299
300
301
302
# File 'lib/inflecto.rb', line 299

def self.classify(table_name)
  # strip out any leading schema name
  camelize(singularize(table_name.to_s.sub(/.*\./, '')))
end

.constantize(input) ⇒ Class, Module

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Find a constant with the name specified in the argument string

The name is assumed to be the one of a top-level constant, constant scope of caller is igored

Examples:


Inflecto.constantize("Module")            # => Module
Inflecto.constantize("DataMapper::Error") # => Test::Unit

Parameters:

  • input (String)

Returns:

  • (Class, Module)


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/inflecto.rb', line 116

def self.constantize(input)
  names = input.split('::')
  names.shift if names.empty? || names.first.empty?

  constant = Object
  names.each do |name|
    # Ruby 1.9 introduces an inherit argument for Module#const_get and
    # #const_defined? and changes their default behavior.
    if Module.method(:const_get).arity == 1
      constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
    else
      constant = constant.const_defined?(name, false) ? constant.const_get(name) : constant.const_missing(name)
    end
  end
  constant
end

.dasherize(input) ⇒ String

Convert input underscores to dashes

Examples:

Inflecto.dasherize("foo_bar") # => "foo-bar"

Parameters:

  • input (String)

Returns:

  • (String)


64
65
66
# File 'lib/inflecto.rb', line 64

def self.dasherize(input)
  input.gsub(/_/, '-')
end

.demodulize(input) ⇒ String

Return unscoped constant name

Examples:


Inflecto.demodulize("DataMapper::Error") # => "Error"
Inflecto.demodulize("DataMapper")        # => "DataMapper"

Parameters:

  • input (String)

Returns:

  • (String)


81
82
83
# File 'lib/inflecto.rb', line 81

def self.demodulize(input)
  input.to_s.gsub(/^.*::/, '')
end

.foreign_key(input) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates a foreign key name

Examples:


Inflecto.foreign_key("Message) => "message_id"

Parameters:

  • input (String)

Returns:

  • (String)


97
98
99
# File 'lib/inflecto.rb', line 97

def self.foreign_key(input)
  "#{underscore(demodulize(input))}_id"
end

.humanize(input) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Humanize string

capitalizes the first word and turns underscores into spaces and strips a # trailing “_id”, if any. Like titleize, this is meant for creating pretty output.

Examples:


Inflecto.humanize("employee_salary") # => "Employee salary"
Inflecto.humanize("author_id")       # => "Author"

Parameters:

  • input (String)

Returns:

  • (String)


251
252
253
254
255
256
# File 'lib/inflecto.rb', line 251

def self.humanize(input)
  result = input.to_s.dup

  inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
  result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
end

.inflectionsInflecto::Inflections

Yields a singleton instance of Inflecto::Inflections

Examples:


Inflecto.inflections do |inflect|
  inflect.uncountable "rails"
end

Returns:



173
174
175
176
177
178
179
# File 'lib/inflecto.rb', line 173

def self.inflections
  if block_given?
    yield Inflections.instance
  else
    Inflections.instance
  end
end

.ordinalize(number) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert a number into an ordinal string

Examples:


ordinalize(1)     # => "1st"
ordinalize(2)     # => "2nd"
ordinalize(1002)  # => "1002nd"
ordinalize(1003)  # => "1003rd"

Parameters:

  • number (Fixnum)

Returns:

  • (String)


148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/inflecto.rb', line 148

def self.ordinalize(number)
  if (11..13).include?(number.to_i % 100)
    "#{number}th"
  else
    case number.to_i % 10
      when 1; "#{number}st"
      when 2; "#{number}nd"
      when 3; "#{number}rd"
      else    "#{number}th"
    end
  end
end

.pluralize(word) ⇒ String

Convert input word string to plural

Examples:


Inflecto.pluralize("post")         # => "posts"
Inflecto.pluralize("octopus")      # => "octopi"
Inflecto.pluralize("sheep")        # => "sheep"
Inflecto.pluralize("words")        # => "words"
Inflecto.pluralize("CamelOctopus") # => "CamelOctopi"

Parameters:

  • word (String)

Returns:

  • (String)


197
198
199
200
201
202
203
204
205
206
# File 'lib/inflecto.rb', line 197

def self.pluralize(word)
  result = word.to_s.dup

  if result.empty? || inflections.uncountables.include?(result.downcase)
    result
  else
    inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
    result
  end
end

.singularize(word) ⇒ String

Convert word to singular

Examples:


Inflecto.singularize("posts") # => "post"
Inflecto.singularize("octopi") # => "octopus"
Inflecto.singularize("sheep") # => "sheep"
Inflecto.singularize("word") # => "word"
Inflecto.singularize("CamelOctopi") # => "CamelOctopus"

Parameters:

  • word (String)

Returns:

  • (String)


224
225
226
227
228
229
230
231
232
233
# File 'lib/inflecto.rb', line 224

def self.singularize(word)
  result = word.to_s.dup

  if inflections.uncountables.any? { |inflection| result =~ /\b(#{inflection})\Z/i }
    result
  else
    inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
    result
  end
end

.tableize(input) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Tabelize input string

Create the name of a table like Rails does for models to table names. This method # uses the pluralize method on the last word in the string.

Examples:


Inflecto.tabelize("RawScaledScorer") # => "raw_scaled_scorers"
Inflecto.tabelize("egg_and_ham")     # => "egg_and_hams"
Inflecto.tabelize("fancyCategory")   # => "fancy_categories"

Parameters:

  • input (String)

Returns:

  • (String)


276
277
278
# File 'lib/inflecto.rb', line 276

def self.tableize(input)
  pluralize(underscore(input).gsub('/','_'))
end

.underscore(input) ⇒ String

Convert input to underscored, lowercase string

Changes ‘::’ to ‘/’ to convert namespaces to paths.

Examples:

Inflecto.underscore("DataMapper")         # => "data_mapper"
Inflecto.underscore("DataMapper::Errors") # => "data_mapper/errors"

Parameters:

  • input (String)

Returns:

  • (String)


43
44
45
46
47
48
49
50
51
# File 'lib/inflecto.rb', line 43

def self.underscore(input)
  word = input.to_s.dup
  word.gsub!(/::/, '/')
  word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
  word.tr!("-", "_")
  word.downcase!
  word
end