Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Add Inflection test (and fixes) to ensure singularizing a singular actually give you the correct singular in more cases #4719

merged 1 commit into from

6 participants


I have a singularize issue, but in running through the some previous singularize issues tonight (#2608 #1825 #2395) I do understand that the current Core position is not to touch the inflections. I get it...but there is a major point release on the horizon, so now is as good a time as any....

I started out just wanting to address the case of singularizing words that end in 'ss'. In the current state "dress".singularize becomes "dres" and "boss" becomes "bos", etc. I think this is beyond just an edge case and should be handled by the framework.

When I got into the code, I realized there was a section for testing that pluralized words returned the expected pluralized versions, but not the same for singular. I added the test for "test_singularize_singular_#{singular}" and to my surprise adding this set of tests caused 13 failures. This may or may not be a surprise to you guys...and there may be a good reason why this set of tests isn't in there.

But in the case that there is not, I made corrections to make that set of tests pass and in the process my double s problem was fixed. (The words 'process' and 'address' were already in the test case and failed when the new set of tests was added.)

I'm open to suggestions on the changes themselves, but do believe that it's a reasonable expectation that the cases tested for work in this case. Thanks!


This commit breaks the action pack tests, specifically:

ruby -I lib:test test/dispatch/routing_test.rb -n test_resources_are_not_pluralized

/cc @fxn


I see the culprit is the ax in

inflect.singular(/(cris|ax|test)(is|es)$/i, '\1is')

Working on it.

Thanks @fxn

(totally prepared for a "this is why inflections are frozen" to follow)




The good news is that the regression uncovered a bogus test in AP, fixed everything in fd5d9b3.

Thanks for hunting it down and fixing it up.


Really nice. I've been bitten by this too. Its nice that the test you added (singularizing singular names) has an existing parallel test in pluralizing pluralized names... makes it seem like this was definitely an oversight.


@josevalim - Thanks for passing it along.

@fxn and/or @jeremy - Any thoughts? (I know it's a very very small piece of Rails, but don't want to let it get forgotten.)


Weekly bump. Still interested in hearing from @fxn or @jeremy as to whether adjusting inflections to better accommodate the singularization of singular words is going to make it in.


@markmcspadden thanks for the ping, I'll try to reply shortly.


As you say the inflector is considered to be frozen. But I am positive about this pull request:

  • First and most important: the loop in the test suite was missing. I think that needs to be fixed, and if in order for the test to pass we need to fix some inflections, so be it.
  • We are going to apply this to master, so heading a major 4.0.

Let's see what does @jeremy think as well.


We have also thumbs up from @jeremy. In then, thanks very much!

@fxn fxn merged commit 6728191 into rails:master
@chancancode chancancode referenced this pull request from a commit in chancancode/rails
@chancancode chancancode Adds missing inflector tests to ensure idempotency
This is a follow up to #4719. It appears that singularize and pluralize
are supposed to be idempotent - i.e. when you call singularize or
pluralize multiple times on the same string, you should get the same
result. (At least for the "officially supported" cases that the stock
inflector is designed to handle.) #4719 added the missing tests for
regular cases, and this commit added the missing tests for the

While I'm at that, I also synced up the irregularity test cases with
the current set of irregularity cases that we ship out-of-the-box.
@senny senny referenced this pull request from a commit in senny/rails
@senny senny CHANGELOG entry for improved singularizing of singulars.
Closes #9559.

The actual patch was added with #4719
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 27, 2012
  1. @markmcspadden

    Add Inflection test (and fixes) to ensure singularizing a singular ac…

    markmcspadden committed
    …tually give you the correct singular in more cases
This page is out of date. Refresh to see the latest.
13 activesupport/lib/active_support/inflections.rb
@@ -23,10 +23,11 @@ module ActiveSupport
inflect.plural(/(quiz)$/i, '\1zes')
inflect.singular(/s$/i, '')
+ inflect.singular(/(ss)$/i, '\1')
inflect.singular(/(n)ews$/i, '\1ews')
inflect.singular(/([ti])a$/i, '\1um')
- inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
- inflect.singular(/(^analy)ses$/i, '\1sis')
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1\2sis')
+ inflect.singular(/(^analy)(sis|ses)$/i, '\1sis')
inflect.singular(/([^f])ves$/i, '\1fe')
inflect.singular(/(hive)s$/i, '\1')
inflect.singular(/(tive)s$/i, '\1')
@@ -36,12 +37,12 @@ module ActiveSupport
inflect.singular(/(m)ovies$/i, '\1ovie')
inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
inflect.singular(/(m|l)ice$/i, '\1ouse')
- inflect.singular(/(bus)es$/i, '\1')
+ inflect.singular(/(bus)(es)?$/i, '\1')
inflect.singular(/(o)es$/i, '\1')
inflect.singular(/(shoe)s$/i, '\1')
- inflect.singular(/(cris|ax|test)es$/i, '\1is')
- inflect.singular(/(octop|vir)i$/i, '\1us')
- inflect.singular(/(alias|status)es$/i, '\1')
+ inflect.singular(/(cris|ax|test)(is|es)$/i, '\1is')
+ inflect.singular(/(octop|vir)(us|i)$/i, '\1us')
+ inflect.singular(/(alias|status)(es)?$/i, '\1')
inflect.singular(/^(ox)en/i, '\1')
inflect.singular(/(vert|ind)ices$/i, '\1ex')
inflect.singular(/(matr)ices$/i, '\1ix')
8 activesupport/test/inflector_test.rb
@@ -65,6 +65,14 @@ def test_uncountable_word_is_not_greedy
assert_equal(plural.capitalize, ActiveSupport::Inflector.pluralize(plural.capitalize))
+ SingularToPlural.each do |singular, plural|
+ define_method "test_singularize_singular_#{singular}" do
+ assert_equal(singular, ActiveSupport::Inflector.singularize(singular))
+ assert_equal(singular.capitalize, ActiveSupport::Inflector.singularize(singular.capitalize))
+ end
+ end
def test_overwrite_previous_inflectors
assert_equal("series", ActiveSupport::Inflector.singularize("series"))
Something went wrong with that request. Please try again.