Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
e1b5e3cc
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
e1b5e3cc
编写于
11月 07, 2009
作者:
Y
Yehuda Katz
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Break up inflector to reduce the dependency burden on dependency-les methods like constantize.
上级
cbded536
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
424 addition
and
409 deletion
+424
-409
actionpack/lib/action_dispatch/http/request.rb
actionpack/lib/action_dispatch/http/request.rb
+1
-0
actionpack/lib/action_dispatch/middleware/stack.rb
actionpack/lib/action_dispatch/middleware/stack.rb
+4
-2
activesupport/lib/active_support/core_ext/string/access.rb
activesupport/lib/active_support/core_ext/string/access.rb
+2
-0
activesupport/lib/active_support/inflector.rb
activesupport/lib/active_support/inflector.rb
+4
-407
activesupport/lib/active_support/inflector/inflections.rb
activesupport/lib/active_support/inflector/inflections.rb
+213
-0
activesupport/lib/active_support/inflector/methods.rb
activesupport/lib/active_support/inflector/methods.rb
+139
-0
activesupport/lib/active_support/inflector/transliterate.rb
activesupport/lib/active_support/inflector/transliterate.rb
+61
-0
未找到文件。
actionpack/lib/action_dispatch/http/request.rb
浏览文件 @
e1b5e3cc
...
...
@@ -6,6 +6,7 @@
require
'active_support/core_ext/array/wrap'
require
'active_support/core_ext/hash/indifferent_access'
require
'active_support/core_ext/object/tap'
require
'active_support/core_ext/string/access'
module
ActionDispatch
class
Request
<
Rack
::
Request
...
...
actionpack/lib/action_dispatch/middleware/stack.rb
浏览文件 @
e1b5e3cc
require
"active_support/inflector/methods"
module
ActionDispatch
class
MiddlewareStack
<
Array
class
Middleware
...
...
@@ -32,7 +34,7 @@ def klass
elsif
@klass
.
respond_to?
(
:call
)
@klass
.
call
else
@klass
.
to_s
.
constantize
ActiveSupport
::
Inflector
.
constantize
(
@klass
.
to_s
)
end
end
...
...
@@ -53,7 +55,7 @@ def ==(middleware)
when
Class
klass
==
middleware
else
klass
==
middleware
.
to_s
.
constantize
klass
==
ActiveSupport
::
Inflector
.
constantize
(
middleware
.
to_s
)
end
end
...
...
activesupport/lib/active_support/core_ext/string/access.rb
浏览文件 @
e1b5e3cc
require
"active_support/multibyte"
class
String
unless
'1.9'
.
respond_to?
(
:force_encoding
)
# Returns the character at the +position+ treating the string as an array (where 0 is the first character).
...
...
activesupport/lib/active_support/inflector.rb
浏览文件 @
e1b5e3cc
# encoding: utf-8
require
'iconv'
require
'active_support/core_ext/object/blank'
require
'active_support/core_ext/string/access'
require
'active_support/core_ext/string/multibyte'
module
ActiveSupport
# The Inflector 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).
module
Inflector
extend
self
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
# inflection rules. Examples:
#
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1\2en'
# inflect.singular /^(ox)en/i, '\1'
#
# inflect.irregular 'octopus', 'octopi'
#
# inflect.uncountable "equipment"
# end
#
# New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
# already have been loaded.
class
Inflections
def
self
.
instance
@__instance__
||=
new
end
attr_reader
:plurals
,
:singulars
,
:uncountables
,
:humans
def
initialize
@plurals
,
@singulars
,
@uncountables
,
@humans
=
[],
[],
[],
[]
end
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
# The replacement should always be a string that may include references to the matched data from the rule.
def
plural
(
rule
,
replacement
)
@uncountables
.
delete
(
rule
)
if
rule
.
is_a?
(
String
)
@uncountables
.
delete
(
replacement
)
@plurals
.
insert
(
0
,
[
rule
,
replacement
])
end
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
# The replacement should always be a string that may include references to the matched data from the rule.
def
singular
(
rule
,
replacement
)
@uncountables
.
delete
(
rule
)
if
rule
.
is_a?
(
String
)
@uncountables
.
delete
(
replacement
)
@singulars
.
insert
(
0
,
[
rule
,
replacement
])
end
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
# for strings, not regular expressions. You simply pass the irregular in singular and plural form.
#
# Examples:
# irregular 'octopus', 'octopi'
# irregular 'person', 'people'
def
irregular
(
singular
,
plural
)
@uncountables
.
delete
(
singular
)
@uncountables
.
delete
(
plural
)
if
singular
[
0
,
1
].
upcase
==
plural
[
0
,
1
].
upcase
plural
(
Regexp
.
new
(
"(
#{
singular
[
0
,
1
]
}
)
#{
singular
[
1
..-
1
]
}
$"
,
"i"
),
'\1'
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"(
#{
plural
[
0
,
1
]
}
)
#{
plural
[
1
..-
1
]
}
$"
,
"i"
),
'\1'
+
plural
[
1
..-
1
])
singular
(
Regexp
.
new
(
"(
#{
plural
[
0
,
1
]
}
)
#{
plural
[
1
..-
1
]
}
$"
,
"i"
),
'\1'
+
singular
[
1
..-
1
])
else
plural
(
Regexp
.
new
(
"
#{
singular
[
0
,
1
].
upcase
}
(?i)
#{
singular
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
upcase
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"
#{
singular
[
0
,
1
].
downcase
}
(?i)
#{
singular
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
downcase
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
upcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
upcase
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
downcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
downcase
+
plural
[
1
..-
1
])
singular
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
upcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
singular
[
0
,
1
].
upcase
+
singular
[
1
..-
1
])
singular
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
downcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
singular
[
0
,
1
].
downcase
+
singular
[
1
..-
1
])
end
end
# Add uncountable words that shouldn't be attempted inflected.
#
# Examples:
# uncountable "money"
# uncountable "money", "information"
# uncountable %w( money information rice )
def
uncountable
(
*
words
)
(
@uncountables
<<
words
).
flatten!
end
# Specifies a humanized form of a string by a regular expression rule or by a string mapping.
# When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
# When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
#
# Examples:
# human /_cnt$/i, '\1_count'
# human "legacy_col_person_name", "Name"
def
human
(
rule
,
replacement
)
@humans
.
insert
(
0
,
[
rule
,
replacement
])
end
# Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
# Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
# <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
#
# Examples:
# clear :all
# clear :plurals
def
clear
(
scope
=
:all
)
case
scope
when
:all
@plurals
,
@singulars
,
@uncountables
=
[],
[],
[]
else
instance_variable_set
"@
#{
scope
}
"
,
[]
end
end
end
# Yields a singleton instance of Inflector::Inflections so you can specify additional
# inflector rules.
#
# Example:
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.uncountable "rails"
# end
def
inflections
if
block_given?
yield
Inflections
.
instance
else
Inflections
.
instance
end
end
# Returns the plural form of the word in the string.
#
# Examples:
# "post".pluralize # => "posts"
# "octopus".pluralize # => "octopi"
# "sheep".pluralize # => "sheep"
# "words".pluralize # => "words"
# "CamelOctopus".pluralize # => "CamelOctopi"
def
pluralize
(
word
)
result
=
word
.
to_s
.
dup
if
word
.
empty?
||
inflections
.
uncountables
.
include?
(
result
.
downcase
)
result
else
inflections
.
plurals
.
each
{
|
(
rule
,
replacement
)
|
break
if
result
.
gsub!
(
rule
,
replacement
)
}
result
end
end
# The reverse of +pluralize+, returns the singular form of a word in a string.
#
# Examples:
# "posts".singularize # => "post"
# "octopi".singularize # => "octopus"
# "sheep".singularize # => "sheep"
# "word".singularize # => "word"
# "CamelOctopi".singularize # => "CamelOctopus"
def
singularize
(
word
)
result
=
word
.
to_s
.
dup
if
inflections
.
uncountables
.
include?
(
result
.
downcase
)
result
else
inflections
.
singulars
.
each
{
|
(
rule
,
replacement
)
|
break
if
result
.
gsub!
(
rule
,
replacement
)
}
result
end
end
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
# is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
#
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
#
# Examples:
# "active_record".camelize # => "ActiveRecord"
# "active_record".camelize(:lower) # => "activeRecord"
# "active_record/errors".camelize # => "ActiveRecord::Errors"
# "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
def
camelize
(
lower_case_and_underscored_word
,
first_letter_in_uppercase
=
true
)
if
first_letter_in_uppercase
lower_case_and_underscored_word
.
to_s
.
gsub
(
/\/(.?)/
)
{
"::
#{
$1
.
upcase
}
"
}.
gsub
(
/(?:^|_)(.)/
)
{
$1
.
upcase
}
else
lower_case_and_underscored_word
.
to_s
.
first
.
downcase
+
camelize
(
lower_case_and_underscored_word
)[
1
..-
1
]
end
end
# Capitalizes all the words and replaces some characters in the string to create
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
# used in the Rails internals.
#
# +titleize+ is also aliased as as +titlecase+.
#
# Examples:
# "man from the boondocks".titleize # => "Man From The Boondocks"
# "x-men: the last stand".titleize # => "X Men: The Last Stand"
def
titleize
(
word
)
humanize
(
underscore
(
word
)).
gsub
(
/\b('?[a-z])/
)
{
$1
.
capitalize
}
end
# The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
#
# Changes '::' to '/' to convert namespaces to paths.
#
# Examples:
# "ActiveRecord".underscore # => "active_record"
# "ActiveRecord::Errors".underscore # => active_record/errors
def
underscore
(
camel_cased_word
)
camel_cased_word
.
to_s
.
gsub
(
/::/
,
'/'
).
gsub
(
/([A-Z]+)([A-Z][a-z])/
,
'\1_\2'
).
gsub
(
/([a-z\d])([A-Z])/
,
'\1_\2'
).
tr
(
"-"
,
"_"
).
downcase
end
# Replaces underscores with dashes in the string.
#
# Example:
# "puni_puni" # => "puni-puni"
def
dasherize
(
underscored_word
)
underscored_word
.
gsub
(
/_/
,
'-'
)
end
# 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:
# "employee_salary" # => "Employee salary"
# "author_id" # => "Author"
def
humanize
(
lower_case_and_underscored_word
)
result
=
lower_case_and_underscored_word
.
to_s
.
dup
inflections
.
humans
.
each
{
|
(
rule
,
replacement
)
|
break
if
result
.
gsub!
(
rule
,
replacement
)
}
result
.
gsub
(
/_id$/
,
""
).
gsub
(
/_/
,
" "
).
capitalize
end
# Removes the module part from the expression in the string.
#
# Examples:
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
# "Inflections".demodulize # => "Inflections"
def
demodulize
(
class_name_in_module
)
class_name_in_module
.
to_s
.
gsub
(
/^.*::/
,
''
)
end
# Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
#
# ==== Examples
#
# 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>
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
.
blank?
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
# Replaces accented characters with their ascii equivalents.
def
transliterate
(
string
)
Iconv
.
iconv
(
'ascii//ignore//translit'
,
'utf-8'
,
string
).
to_s
end
if
RUBY_VERSION
>=
'1.9'
undef_method
:transliterate
def
transliterate
(
string
)
warn
"Ruby 1.9 doesn't support Unicode normalization yet"
string
.
dup
end
# The iconv transliteration code doesn't function correctly
# on some platforms, but it's very fast where it does function.
elsif
"foo"
!=
(
Inflector
.
transliterate
(
"föö"
)
rescue
nil
)
undef_method
:transliterate
def
transliterate
(
string
)
string
.
mb_chars
.
normalize
(
:kd
)
.
# Decompose accented characters
gsub
(
/[^\x00-\x7F]+/
,
''
)
# Remove anything non-ASCII entirely (e.g. diacritics).
end
end
# 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
# "RawScaledScorer".tableize # => "raw_scaled_scorers"
# "egg_and_ham".tableize # => "egg_and_hams"
# "fancyCategory".tableize # => "fancy_categories"
def
tableize
(
class_name
)
pluralize
(
underscore
(
class_name
))
end
# 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:
# "egg_and_hams".classify # => "EggAndHam"
# "posts".classify # => "Post"
#
# Singular names are not handled correctly:
# "business".classify # => "Busines"
def
classify
(
table_name
)
# strip out any leading schema name
camelize
(
singularize
(
table_name
.
to_s
.
sub
(
/.*\./
,
''
)))
end
# Creates a foreign key name from a class name.
# +separate_class_name_and_id_with_underscore+ sets whether
# the method should put '_' between the name and 'id'.
#
# Examples:
# "Message".foreign_key # => "message_id"
# "Message".foreign_key(false) # => "messageid"
# "Admin::Post".foreign_key # => "post_id"
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
# 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
# Tries to find a constant with the name specified in the argument string:
#
# "Module".constantize # => Module
# "Test::Unit".constantize # => Test::Unit
#
# The name is assumed to be the one of a top-level constant, no matter whether
# it starts with "::" or not. No lexical context is taken into account:
#
# C = 'outside'
# module M
# C = 'inside'
# C # => 'inside'
# "C".constantize # => 'outside', same as ::C
# end
#
# NameError is raised when the name is not in CamelCase or the constant is
# unknown.
def
constantize
(
camel_cased_word
)
names
=
camel_cased_word
.
split
(
'::'
)
names
.
shift
if
names
.
empty?
||
names
.
first
.
empty?
constant
=
Object
names
.
each
do
|
name
|
constant
=
constant
.
const_defined?
(
name
)
?
constant
.
const_get
(
name
)
:
constant
.
const_missing
(
name
)
end
constant
end
else
def
constantize
(
camel_cased_word
)
#:nodoc:
names
=
camel_cased_word
.
split
(
'::'
)
names
.
shift
if
names
.
empty?
||
names
.
first
.
empty?
constant
=
Object
names
.
each
do
|
name
|
constant
=
constant
.
const_get
(
name
,
false
)
||
constant
.
const_missing
(
name
)
end
constant
end
end
# Turns a number into an ordinal string used to denote the position in an
# ordered sequence such as 1st, 2nd, 3rd, 4th.
#
# Examples:
# ordinalize(1) # => "1st"
# ordinalize(2) # => "2nd"
# ordinalize(1002) # => "1002nd"
# ordinalize(1003) # => "1003rd"
def
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
end
end
# in case active_support/inflector is required without the rest of active_support
require
'active_support/inflector/inflections'
require
'active_support/inflector/transliterate'
require
'active_support/inflector/methods'
require
'active_support/inflections'
require
'active_support/core_ext/string/inflections'
activesupport/lib/active_support/inflector/inflections.rb
0 → 100644
浏览文件 @
e1b5e3cc
# require "active_support/core_ext/string/access"
module
ActiveSupport
module
Inflector
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
# inflection rules. Examples:
#
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1\2en'
# inflect.singular /^(ox)en/i, '\1'
#
# inflect.irregular 'octopus', 'octopi'
#
# inflect.uncountable "equipment"
# end
#
# New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
# already have been loaded.
class
Inflections
def
self
.
instance
@__instance__
||=
new
end
attr_reader
:plurals
,
:singulars
,
:uncountables
,
:humans
def
initialize
@plurals
,
@singulars
,
@uncountables
,
@humans
=
[],
[],
[],
[]
end
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
# The replacement should always be a string that may include references to the matched data from the rule.
def
plural
(
rule
,
replacement
)
@uncountables
.
delete
(
rule
)
if
rule
.
is_a?
(
String
)
@uncountables
.
delete
(
replacement
)
@plurals
.
insert
(
0
,
[
rule
,
replacement
])
end
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
# The replacement should always be a string that may include references to the matched data from the rule.
def
singular
(
rule
,
replacement
)
@uncountables
.
delete
(
rule
)
if
rule
.
is_a?
(
String
)
@uncountables
.
delete
(
replacement
)
@singulars
.
insert
(
0
,
[
rule
,
replacement
])
end
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
# for strings, not regular expressions. You simply pass the irregular in singular and plural form.
#
# Examples:
# irregular 'octopus', 'octopi'
# irregular 'person', 'people'
def
irregular
(
singular
,
plural
)
@uncountables
.
delete
(
singular
)
@uncountables
.
delete
(
plural
)
if
singular
[
0
,
1
].
upcase
==
plural
[
0
,
1
].
upcase
plural
(
Regexp
.
new
(
"(
#{
singular
[
0
,
1
]
}
)
#{
singular
[
1
..-
1
]
}
$"
,
"i"
),
'\1'
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"(
#{
plural
[
0
,
1
]
}
)
#{
plural
[
1
..-
1
]
}
$"
,
"i"
),
'\1'
+
plural
[
1
..-
1
])
singular
(
Regexp
.
new
(
"(
#{
plural
[
0
,
1
]
}
)
#{
plural
[
1
..-
1
]
}
$"
,
"i"
),
'\1'
+
singular
[
1
..-
1
])
else
plural
(
Regexp
.
new
(
"
#{
singular
[
0
,
1
].
upcase
}
(?i)
#{
singular
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
upcase
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"
#{
singular
[
0
,
1
].
downcase
}
(?i)
#{
singular
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
downcase
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
upcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
upcase
+
plural
[
1
..-
1
])
plural
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
downcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
plural
[
0
,
1
].
downcase
+
plural
[
1
..-
1
])
singular
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
upcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
singular
[
0
,
1
].
upcase
+
singular
[
1
..-
1
])
singular
(
Regexp
.
new
(
"
#{
plural
[
0
,
1
].
downcase
}
(?i)
#{
plural
[
1
..-
1
]
}
$"
),
singular
[
0
,
1
].
downcase
+
singular
[
1
..-
1
])
end
end
# Add uncountable words that shouldn't be attempted inflected.
#
# Examples:
# uncountable "money"
# uncountable "money", "information"
# uncountable %w( money information rice )
def
uncountable
(
*
words
)
(
@uncountables
<<
words
).
flatten!
end
# Specifies a humanized form of a string by a regular expression rule or by a string mapping.
# When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
# When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
#
# Examples:
# human /_cnt$/i, '\1_count'
# human "legacy_col_person_name", "Name"
def
human
(
rule
,
replacement
)
@humans
.
insert
(
0
,
[
rule
,
replacement
])
end
# Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
# Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
# <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
#
# Examples:
# clear :all
# clear :plurals
def
clear
(
scope
=
:all
)
case
scope
when
:all
@plurals
,
@singulars
,
@uncountables
=
[],
[],
[]
else
instance_variable_set
"@
#{
scope
}
"
,
[]
end
end
end
# Yields a singleton instance of Inflector::Inflections so you can specify additional
# inflector rules.
#
# Example:
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.uncountable "rails"
# end
def
inflections
if
block_given?
yield
Inflections
.
instance
else
Inflections
.
instance
end
end
# Returns the plural form of the word in the string.
#
# Examples:
# "post".pluralize # => "posts"
# "octopus".pluralize # => "octopi"
# "sheep".pluralize # => "sheep"
# "words".pluralize # => "words"
# "CamelOctopus".pluralize # => "CamelOctopi"
def
pluralize
(
word
)
result
=
word
.
to_s
.
dup
if
word
.
empty?
||
inflections
.
uncountables
.
include?
(
result
.
downcase
)
result
else
inflections
.
plurals
.
each
{
|
(
rule
,
replacement
)
|
break
if
result
.
gsub!
(
rule
,
replacement
)
}
result
end
end
# The reverse of +pluralize+, returns the singular form of a word in a string.
#
# Examples:
# "posts".singularize # => "post"
# "octopi".singularize # => "octopus"
# "sheep".singularize # => "sheep"
# "word".singularize # => "word"
# "CamelOctopi".singularize # => "CamelOctopus"
def
singularize
(
word
)
result
=
word
.
to_s
.
dup
if
inflections
.
uncountables
.
include?
(
result
.
downcase
)
result
else
inflections
.
singulars
.
each
{
|
(
rule
,
replacement
)
|
break
if
result
.
gsub!
(
rule
,
replacement
)
}
result
end
end
# 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:
# "employee_salary" # => "Employee salary"
# "author_id" # => "Author"
def
humanize
(
lower_case_and_underscored_word
)
result
=
lower_case_and_underscored_word
.
to_s
.
dup
inflections
.
humans
.
each
{
|
(
rule
,
replacement
)
|
break
if
result
.
gsub!
(
rule
,
replacement
)
}
result
.
gsub
(
/_id$/
,
""
).
gsub
(
/_/
,
" "
).
capitalize
end
# Capitalizes all the words and replaces some characters in the string to create
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
# used in the Rails internals.
#
# +titleize+ is also aliased as as +titlecase+.
#
# Examples:
# "man from the boondocks".titleize # => "Man From The Boondocks"
# "x-men: the last stand".titleize # => "X Men: The Last Stand"
def
titleize
(
word
)
humanize
(
underscore
(
word
)).
gsub
(
/\b('?[a-z])/
)
{
$1
.
capitalize
}
end
# 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
# "RawScaledScorer".tableize # => "raw_scaled_scorers"
# "egg_and_ham".tableize # => "egg_and_hams"
# "fancyCategory".tableize # => "fancy_categories"
def
tableize
(
class_name
)
pluralize
(
underscore
(
class_name
))
end
# 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:
# "egg_and_hams".classify # => "EggAndHam"
# "posts".classify # => "Post"
#
# Singular names are not handled correctly:
# "business".classify # => "Busines"
def
classify
(
table_name
)
# strip out any leading schema name
camelize
(
singularize
(
table_name
.
to_s
.
sub
(
/.*\./
,
''
)))
end
end
end
\ No newline at end of file
activesupport/lib/active_support/inflector/methods.rb
0 → 100644
浏览文件 @
e1b5e3cc
module
ActiveSupport
# The Inflector 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).
module
Inflector
extend
self
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
# is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
#
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
#
# Examples:
# "active_record".camelize # => "ActiveRecord"
# "active_record".camelize(:lower) # => "activeRecord"
# "active_record/errors".camelize # => "ActiveRecord::Errors"
# "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
def
camelize
(
lower_case_and_underscored_word
,
first_letter_in_uppercase
=
true
)
if
first_letter_in_uppercase
lower_case_and_underscored_word
.
to_s
.
gsub
(
/\/(.?)/
)
{
"::
#{
$1
.
upcase
}
"
}.
gsub
(
/(?:^|_)(.)/
)
{
$1
.
upcase
}
else
lower_case_and_underscored_word
.
to_s
[
0
].
chr
.
downcase
+
camelize
(
lower_case_and_underscored_word
)[
1
..-
1
]
end
end
# The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
#
# Changes '::' to '/' to convert namespaces to paths.
#
# Examples:
# "ActiveRecord".underscore # => "active_record"
# "ActiveRecord::Errors".underscore # => active_record/errors
def
underscore
(
camel_cased_word
)
camel_cased_word
.
to_s
.
gsub
(
/::/
,
'/'
).
gsub
(
/([A-Z]+)([A-Z][a-z])/
,
'\1_\2'
).
gsub
(
/([a-z\d])([A-Z])/
,
'\1_\2'
).
tr
(
"-"
,
"_"
).
downcase
end
# Replaces underscores with dashes in the string.
#
# Example:
# "puni_puni" # => "puni-puni"
def
dasherize
(
underscored_word
)
underscored_word
.
gsub
(
/_/
,
'-'
)
end
# Removes the module part from the expression in the string.
#
# Examples:
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
# "Inflections".demodulize # => "Inflections"
def
demodulize
(
class_name_in_module
)
class_name_in_module
.
to_s
.
gsub
(
/^.*::/
,
''
)
end
# Creates a foreign key name from a class name.
# +separate_class_name_and_id_with_underscore+ sets whether
# the method should put '_' between the name and 'id'.
#
# Examples:
# "Message".foreign_key # => "message_id"
# "Message".foreign_key(false) # => "messageid"
# "Admin::Post".foreign_key # => "post_id"
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
# 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
# Tries to find a constant with the name specified in the argument string:
#
# "Module".constantize # => Module
# "Test::Unit".constantize # => Test::Unit
#
# The name is assumed to be the one of a top-level constant, no matter whether
# it starts with "::" or not. No lexical context is taken into account:
#
# C = 'outside'
# module M
# C = 'inside'
# C # => 'inside'
# "C".constantize # => 'outside', same as ::C
# end
#
# NameError is raised when the name is not in CamelCase or the constant is
# unknown.
def
constantize
(
camel_cased_word
)
names
=
camel_cased_word
.
split
(
'::'
)
names
.
shift
if
names
.
empty?
||
names
.
first
.
empty?
constant
=
Object
names
.
each
do
|
name
|
constant
=
constant
.
const_defined?
(
name
)
?
constant
.
const_get
(
name
)
:
constant
.
const_missing
(
name
)
end
constant
end
else
def
constantize
(
camel_cased_word
)
#:nodoc:
names
=
camel_cased_word
.
split
(
'::'
)
names
.
shift
if
names
.
empty?
||
names
.
first
.
empty?
constant
=
Object
names
.
each
do
|
name
|
constant
=
constant
.
const_get
(
name
,
false
)
||
constant
.
const_missing
(
name
)
end
constant
end
end
# Turns a number into an ordinal string used to denote the position in an
# ordered sequence such as 1st, 2nd, 3rd, 4th.
#
# Examples:
# ordinalize(1) # => "1st"
# ordinalize(2) # => "2nd"
# ordinalize(1002) # => "1002nd"
# ordinalize(1003) # => "1003rd"
def
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
end
end
\ No newline at end of file
activesupport/lib/active_support/inflector/transliterate.rb
0 → 100644
浏览文件 @
e1b5e3cc
# encoding: utf-8
require
'iconv'
require
'active_support/core_ext/string/multibyte'
module
ActiveSupport
module
Inflector
extend
self
# Replaces accented characters with their ascii equivalents.
def
transliterate
(
string
)
Iconv
.
iconv
(
'ascii//ignore//translit'
,
'utf-8'
,
string
).
to_s
end
if
RUBY_VERSION
>=
'1.9'
undef_method
:transliterate
def
transliterate
(
string
)
warn
"Ruby 1.9 doesn't support Unicode normalization yet"
string
.
dup
end
# The iconv transliteration code doesn't function correctly
# on some platforms, but it's very fast where it does function.
elsif
"foo"
!=
(
Inflector
.
transliterate
(
"föö"
)
rescue
nil
)
undef_method
:transliterate
def
transliterate
(
string
)
string
.
mb_chars
.
normalize
(
:kd
)
.
# Decompose accented characters
gsub
(
/[^\x00-\x7F]+/
,
''
)
# Remove anything non-ASCII entirely (e.g. diacritics).
end
end
# Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
#
# ==== Examples
#
# 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>
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
end
end
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录