Watching the RSS feed from the Ruby on Rails trac is a great way to keep up on what's happening in Rails development. If you're doing any development on the Ruby on Rails project it's required reading. Even if you just are using Rails for a web app, it's useful to keep up on what bugs people are reporting.
Lately I've noticed a slew of bugs being opened against the Inflector, the class in Rails that transforms words from one form to another: singular to plural, classname to tablename, etc. The bugs all complain that Inflector is getting a pluralization or singularization wrong. But this isn't a bug in Inflector, it is just an inherent limitation of how it works. But fear not, there is a better solution than opening a bug against the Inflector.
I guess this has been a constant thing over the history of Rails, but since it's still going on, it deserves a rehash.
Class Inflector has a bunch of regular expressions it uses to match a word then transform it from singular to plural or plural to singular. It's a pretty clever but fundamentally limited piece of code, as it relies on a list of special cases to do its work.
You can see all the standard rules for pluralization and singularization in inflections.rb in the ActiveSupport library. Notice there are only 18 rules for pluralization, which is not going to cover all the vagaries of the English language. Given the highly irregular nature of English, it would be a daunting task to create an exhaustive list of rules for pluraliztion, and that's even ignoring neologisms and ad-hoc corruptions. Rails solves the problem by allowing each project to define its own set of custom rules for singular and plural forms.
If the inflector is not handling any of your model names correctly, don't open a bug on it. Instead, go to the environments.rb file in your project and add your own rules for the names of the models in question.
At the end of environments.rb you'll see the following commented out block of code:
# Inflector.inflections do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end
Uncomment the block and put your own rules in it. See the docs on Inflections for the detailed API.
Inflector.inflections do |inflect| inflect.irregular 'leaf', 'leaves' inflect.irregular 'staff', 'staves' end
irregular method is most convenient to create a rule for a particular word. If you want to use a regular expression for several similar words, use the
singular methods (you need a matched set of them both, or only one direction will work). And of course
uncountable indicates a word is the same in both singular and plural forms.
So that's it. Don't be creating any more pluralization bug tickets. Just use the handy Inflector interface to customize pluralizations for yourself.