yeah what is that

Jared Carroll

Now most of the Rails community is familiar with map.resources since it was officially released in Rails 1.2.3. But another method came with it that I’ve never used or seen anyone use. So I decided to investigate it.

Looking at the doc for ActionController::Resources#resource it says

No default index, new, or create routes are created for the singleton resource controller.

OK, so it looks like I shouldn’t be creating these things with HTML forms. My first impression was that #resource was for one-to-one associations but that doesn’t seem to be the case.

Some further reading says #resource only gives you #new and #edit named routes.

OK, so it looks like I can view and edit these things and not delete them.

Here’s what I think they should be used for.

Say we have users in our system. And users have some attributes that are central (and are usually required) to a user:

  • email
  • password
  • name

As well as several attributes that seem to be related to their profile (and are usually optional):

  • age
  • date_of_birth
  • bio

Now you could say we have 2 objects here:

  • User
  • Profile

And a User has_one Profile. But lets keep it simple and instead put everything in the users table.

A client is then going to ask can we have 2 separate pages for viewing/editing our basic user information and our profile information?.

Our first implementation might look like this:

class UsersController < ApplicationController

  def new

  def create

  def show

  def edit

  def update

  def profile

  def edit_profile


Look at those 2 ugly actions:

  • profile
  • edit_profile

Lets move them into a separate profiles controller so we can stay with the CRUD action naming convention.

class ProfilesController < ApplicationController

  def show

  def edit


We don’t need an #update action in our ProfilesController because the #edit form will POST to UsersController#update because it is editing a User anyway.

Here’s our routes file:

In config/routes.rb:

ActionController::Routing::Routes.draw do |map|

  map.resources :users do |user|
    user.resource :profile


That #resource gives us:


And some named routes:


Now we have actions whos names don’t stray from the basic CRUD naming conventions and also get some free named routes from Rails.

Has anyone else used #resource? And what for?