This project is archived and is in readonly mode.
[PATCH] Uncountable singularize uses regex match while pluralize uses exact match leading leading to unexpected collisions
Reported by John Paul Ashenfelter | November 30th, 2010 @ 06:37 PM | in 3.0.5
I have an model named "ors" which is both singular and plural (e.g. it's uncountable)
ActiveSupport::Inflector.inflections do |inflect|
inflect.uncountable %w( ors )
end
The inflector works beautifully
"ors".pluralize => "ors"
"ors".singularize => "ors"
"ors".pluralize.singularize => "ors"
Then I add some scaffolding for my Sponsor model and everything goes crazy with the tests -- long story short the pluralization/singularization is not right. I try the same inflecting:
"sponsor".pluralize => "sponsors"
"sponsors".singularize => "sponsors"
"sponsor".pluralize.singularize => "sponsors"
After some WTF time, I try a clean Rails3 project and "sponsors".singularize => "sponsor" as expected, so I realize it might be the "ors" inflection. I add the uncountable "ors" inflection to the clean Rails3 project and get the problematic "sponsors" singular inflection. I remove it, problem stops. I verify it with "razors" to make sure I'm not crazy:
"razor".pluralize => "razors"
"razors".singularize => "razors"
"razor".pluralize.singularize => "razors"
I'm going to assume this was not the intended behavior but I know there's lots of back and forth discussion on inflections and lack of interest in changing them. The core problem for me here was that setting an uncountable inflection had the side effect of changing a number of other inflections (sponsor, donor, razor). The reason I think it's a bug is that it's not reflexive -- "string".pluralize.singularize == "string" IMHO.
The problem is in #singularize on line 151 of https://github.com/rails/rails/blob/4eab983b955fe17cf02c6fe96cab1c8...
151 if inflections.uncountables.any? { |inflection| result =~ /#{inflection}\Z/i }
The matching #pluralize is specific
132 if word.empty? || inflections.uncountables.include?(result.downcase)
For what it's worth, I couldn't get "ors" to work as an irregular either since that generates ending/suffix matches instead of word matches.
I looked at the tests in ActiveSupport::Inflections and it's also silent on the details of irregular words:
jeans => jeans
funky jeans => funky jeans
bluejeans => ... (it's not there to settle the issue)
If the intention is matching the ending fragment, as #singularize is currently written, then
bluejeans => bluejeans
sponsors => sponsors
given inflect.uncountables = %w( jeans ors)
This is definitely broken for the word "sponsors" since there is a singular that's different.
If instead, the intention is the word, as "funky jeans" suggests, then adding a word boundary to the regex fixes "sponsors" and retains "funky jeans". But it breaks "bluejeans"
It seems like I'm making a big deal, bit the key thing for me is that I can't use "ors" as an @uncountable without breaking things and I can't use it as an irregular because the singular and plurals generated from that match and word containing /or(s)/. Right now, my only solution other than refactoring the name of the object is to manually set the singular and plural
inflect.plural /^(ors)$/i, '\1'
inflect.singular /^(ors)$/i, '\1'
I would have thought that was what uncountable was supposed to do.
Comments and changes to this ticket
-
John Paul Ashenfelter November 30th, 2010 @ 06:53 PM
- no changes were found...
-
John Paul Ashenfelter November 30th, 2010 @ 06:55 PM
- Tag set to bug, patch
-
John Paul Ashenfelter November 30th, 2010 @ 06:56 PM
- Title changed from Uncountable singularize uses regex match while pluralize uses exact match leading leading to unexpected collisions to [PATCH] Uncountable singularize uses regex match while pluralize uses exact match leading leading to unexpected collisions
-
John Paul Ashenfelter November 30th, 2010 @ 07:11 PM
- Tag changed from bug, patch to activesupport, bug, patch
-
Aditya Sanghi December 1st, 2010 @ 08:55 AM
- State changed from new to open
- Milestone cleared.
- Assigned user set to Xavier Noria
- Importance changed from to Low
-
Piotr Sarnacki December 18th, 2010 @ 08:53 AM
John: only one thing, you should move the last line of second test to ensure:
ensure ActiveSupport::Inflector.inflections.instance_variable_set :@uncountables, cached_uncountables end
if that test breaks, other tests will not break because of that.
-
Repository December 22nd, 2010 @ 08:45 AM
- State changed from open to resolved
(from [9b4622a483319f3d1e7f4489442f0d86afb6da36]) Added a word boundary to uncountable inflection regex for #singularize so short inflections like ors do not affect larger words like sponsors [#6093 state:resolved] https://github.com/rails/rails/commit/9b4622a483319f3d1e7f4489442f0...
-
Repository December 22nd, 2010 @ 08:48 AM
(from [cad4f0030969476941ec62096b9c84070355b823]) Added a word boundary to uncountable inflection regex for #singularize so short inflections like ors do not affect larger words like sponsors [#6093 state:resolved] https://github.com/rails/rails/commit/cad4f0030969476941ec62096b9c8...
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Attachments
Tags
Referenced by
- 6040 ActiveSupport - Incorrect Inflectors for "nurseries" There is a patch available in #6093
- 6093 [PATCH] Uncountable singularize uses regex match while pluralize uses exact match leading leading to unexpected collisions (from [9b4622a483319f3d1e7f4489442f0d86afb6da36]) Added a...
- 6093 [PATCH] Uncountable singularize uses regex match while pluralize uses exact match leading leading to unexpected collisions (from [cad4f0030969476941ec62096b9c84070355b823]) Added a...