Singular and Plural in Rails

January 7th, 2008

One powerful and confusing thing in rails is how it wires up different things (database tables, models, controllers, urls…) with the “same” name. Rails uses both singular and plural, and is opinionated about grammar. One clue about what Rails wants is what happens when you generate a resource.

> ./script/generate resource pancake
      create  db/migrate/001_create_pancakes.rb # plural 
      create  app/models/pancake.rb # singular
      create  test/unit/pancake_test.rb # singular
      create  test/fixtures/pancakes.yml # plural
      create  app/controllers/pancakes_controller.rb # plural
      create  test/functional/pancakes_controller_test.rb # plural
      create  app/views/pancakes # plural
      create  app/helpers/pancakes_helper.rb # plural
      route  map.resources :pancakes # plural

The database table is plural.

db/migrate/001_create_pancakes.rb
1
2
3
class CreatePancakes < ActiveRecord::Migration
  def self.up
    create_table :pancakes do |t|

The model is singular, and associations are pluralization sensitive (the associations should be easy).

app/models/pancake.rb
1
2
3
class Pancake < ActiveRecord::Base
  belongs_to :eater # singular
  has_many :ingredients # plural

This is probably the confusing part: resource-based controllers should be plural (which means the directory for the views and the helper is also plural).

app/controllers/pancake_controller.rb
1
class PancakesController < ApplicationController

The route name and the urls it generates/recognizes are plural.

config/routes.rb
1
2
  # /pancakes/:id => PancakesController#show, etc
  map.resources :pancakes

The rake routes command (also a good reminder of what to call your controller actions) will tell you what routes are generated from this. Here are a few of the pancake routes:

> rake routes
# named route HTTP verb path generated parameters
pancakes GET /pancakes {:controller=>”pancakes”, :action=>”index”}
  POST /pancakes {:controller=>”pancakes”, :action=>”create”}
pancake GET /pancakes/:id {:controller=>”pancakes”, :action=>”show”}

(Is this right? Or am I still confused?)

Sorry, comments are closed for this article.