Rails HowTo: Pluralizing

Into JavaScript? Have I got good news for you!

If you’re interested in JavaScript-driven web apps, snazzy visual fx, and generally confusing people into thinking your site is Flash—but oh-so-much better—you should buy our JavaScript Performance Rocks! book while it’s still in beta. Written by Thomas Fuchs, the creator of Scriptaculous, and yours truly, the maker of funny jokes and shiny graphics.

We cover everything from The Most Ridiculous Performance Fix Ever (and it is ridiculous), to serving strategies, DOM diets, loop unrolling (for those really extreme cases), how to play nice with the garbage collector, and everything in between. And it comes with our custom profiling tool, The DOM Monster, which analyzes your pages and suggests fixes. This package is only $24 right now but will be $29 as soon as it’s done, in mid-June 2009… but if you snag your copy today, you get the final version by email just as soon as it’s ready and save a noteworthy 5 bux! You can’t lose.

Right now I’m working on going through the comments on my last post and picking out questions to answer. Here’s the first one.

Cheese, or cheeses? This is the question. It depends on whether what you’re talking about is a controller, model, or database table. The rules for Rails’ pluralization are simple:

  • Models are singular—Cheese.find() sounds better than Cheeses.find()
  • Database table names are plural—mydatabase.cheeses instead of mydatabase.cheese
  • Controllers are plural—The People Controller, The Accounts Controller

Furthermore, Rails’ use of pluralization is pretty smart, albeit not perfect. From “person” you get “people,” and “mouse” you get “mice.” If you’re tracking deer, though, watch out for “deers.”

Why?

So that Rails, like Ruby itself, can be not only code but conversational English.

“In the People controller’s search action, we look for a Person with the ID of [insertidhere].”

“A Person belongs to an Account, but the Cheese stands alone.”

You can also read this blog post by David about pluralization. If you dare.

How?

Rails does its pluralizations with the Inflector class. It’s got a bunch of methods in there for doing fun things with words or phrases, including:

  • pluralize() duh
  • singularize() an awkward word if there ever was
  • ordinalize() turns a number 1 into 1st, 2 into 2nd, etc.
  • humanize() turns underscored_lowercase_phrases into “Underscored Lowercase Phrases” “Underscored lowercase phrases”

This is also where you’ll find the methods Rails uses to figure out table names for compound words (e.g. HeresATableName into heres_a_table_name) and so on.

They’re There for You to Use

You can use these in your controllers, views, and whatnot, if you like. The main functions you might be using there are mixed into the String class, so you can do:

<%= "Person".pluralize %>

And ordinalize() has been mixed into the Integer class, as well.

Note: If you go read the class docs and click “show source” under each method, you’ll find they’re all pretty easy to read, with a minimum of crazy interdependence. If you want to take a peek into the Rails source in general, Inflector’s a good place to start.

How Can I Work Around It?

When you create a scaffold, using the following line, it will create both a model and controller and it’ll pluralize the controller:

script/generate scaffold cheese

If you really want cheese instead of cheeses, you can create a controller alone instead of scaffolding:

script/generate controller cheese

And it’ll take what you give it at face value, assuming you’ve taken hours to agonize over whether or not this is the right decision.

If you don’t want your table name to be plural, you can override it in your model file using the set_table_name() method (see this wiki page).

That’s Really Intere—Ooo, Shiny!

If you’re intrigued by the Inflector, as I was at first, you can make it your bitc—err, I mean, play with it—using Rails’ built-in console.

Just pop open your not-so-friendly local command line, cd into your app’s directory and run script/console like thus:

shiny:~/Sites/mynewproject amy$ script/console
Loading development environment.

Inflector.pluralize('test') => "tests" Inflector.pluralize('mouse') => "mice" Inflector.pluralize('geese') => "geeses" "mouse".pluralize => "mice" exit 1.ordinalize => "1st"

Yes, my computer’s name is shiny. It is shiny, too.

16 Comments

  1. BL says:

    Thanks for the great article. I just thought I’d point out a quick problem with it though: in the part where you are talking about the humanize function, there is a formatting error where it italicized the "lowercase" instead of having _’s around it.

  2. Amy Hoy says:

    So it is, BL. I already caught one of those before. I love Markdown, but sometimes it’s silly! Thanks. :)

  3. matt says:

    Nice – You might want to check out the pluralizer at nubyOnRails (nOr)

    http://nubyonrails.topfunky.com/tools/pluralize

  4. Iain says:

    Umm, "geese" is the plural of "goose". I guess that just demonstrates you’d shouldn’t place blind trust in the pluralizer.

  5. Amy Hoy says:

    Iain, yes, that’s what I was trying to show. :) It’s software and imperfect; English is tough.

    &gt;&gt; Inflector.pluralize(‘goose’) =&gt; "gooses"

    &gt;&gt; Inflector.pluralize(‘deer’) =&gt; "deers"

  6. I dared and I still like the way you do it better baby!

    I mean speaking of oneself is not for the softhearted but saying "all genuises are a little crazy" when speaking of oneself… Signallers are getting on my nerves…

  7. rick says:

    What is this Inflector nonsense? Rails puts those methods on String.

    ‘beer’.pluralize =&gt; ‘beers’ # much better

    and don’t forget this in your views:

    I drank &lt;%= pluralize 5, ‘beer’ %&gt;.

  8. Thanks for the great post, I’m still in the ‘trying to craete time to play with Rails’ stage but I’m always interested to learn more about it’s workings.

    You have a very clear and easy to understand style which was a pleasure to read over my morning coffee!

  9. Ladislav Martincik says:

    irb

    irb(main):001:0&gt; require ‘active_support’ =&gt; true irb(main):002:0&gt; "person".pluralize =&gt; "people" irb(main):003:0&gt;

  10. Well now that’s good blog writing. You have found another reader ;)

  11. Shaun says:

    My powerbook isn’t named shiny but I do call it shiny affectionately :)

    I found this very useful, you have a great way of explaining things. Thank you

  12. […] believe me yet? Pluralize is another. Rails can automagically pluralize words like “user” or “person”. 1 person, 2 people. Rails gives this to you […]

  13. […] so on http://slash7.com/2005/11/17/rails-howto-pluralizing/ ‹Previous Post Getting Motivated About Email Next Post Going to […]

  14. […] method. Rails does its pluralizations with the Inflector class. You can read all about it from Amy Hoy: Rails’ use of pluralization is pretty smart, albeit not perfect. From “person” you get […]

Hey, why not get a shiny
Freckle Time Tracking
account?