Rails HowTo: Pluralizing

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.

posted in: articles, rails, tips and tricks    |     12 comments