RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


A Flickr-based Introduction to Ruby on Rails 2.0 : Page 4

Want to get started with Rails 2.0? Explore some of the most prominent new features, and learn how to use them to build a simple, but visually attractive, web application based on Flickr.

Nested Resources to Build Expressive URLs
At this point, you've learned about RailTrackr's capability to serve resources using REST URLs, such as:
  • http://yoursite.com/flickr_users/max: Show details for Flickr user max
  • http://yoursite.com/photosets/123: Show photoset with ID 123
  • http://yoursite.com/photos/456/edit: Edit photo with ID 456

In fact, if you take a look at the basic resource mapping in the routes.rb file, you'll notice that the scaffolding commands have created the following entries:

ActionController::Routing::Routes.draw do |map|
  map.resources :photos
  map.resources :photosets
  map.resources :flickr_users

  # default mapping
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'

Rails 2.0 offers a way to further improve URLs and make them more readable. Just like the way you configure a one-to-many relationship in ActiveRecord models, you can now declare mappings between resources and use URLs like these ones to navigate across the references:

  • http://yoursite.com/flickr_users/max/photosets: Show all max's photosets
  • http://yoursite.com/photosets/123/photos: Show all photos within photoset 123

These URLs have more natural names that are easier to remember, and activating them requires just two steps. First, change the routes.rb to reflect the following contents:

ActionController::Routing::Routes.draw do |map|
  map.resources :flickr_users
  map.resources :flickr_users, :has_many => :photosets   
  map.resources :photosets, :has_many => :photos

  # default mapping
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'

Then modify your controller by declaring resource mapping between users and their photosets as follows:

class PhotosetsController < ApplicationController
  before_filter :load_user
  # Given a sample url like site.com/flickr_user/max/photosets ,
  # params[:flickr_user_id] automagically points to 'max'
  def load_user   
    @flickr_user = FlickrUser.find(params[:flickr_user_id])
  # GET /photosets
  def index
    @photosets = Photoset.by_user(@flickr_user)[0..50]

    respond_to do |format|
      format.html # index.html.erb

The before_filter statement ensures that the user is loaded before accessing his photosets. The flickr_user_id variable is automatically populated by Rails using a naming convention from the name of the parent resource (flickr_user).

You can use this nested resource mapping not only within controllers but also to generate URLs in your views. Suppose the @flickr_user points to the user with ID max and the @photoset to one of his photosets with ID 123, all the following statements can be legally used within views to generate URLs that you can associate to linking functions such as link_to:

  • flickr_user_photosets_url(@flickr_user) will point to www.site.com/flickr_user/max/photosets (list of all the user's photosets)
  • flickr_user_photoset_url(@flickr_user,@photoset) will point to www.site.com/flickr_user/max/photoset/123 (details of one specific photoset)
  • photoset_photos_url(@photoset) will point to www.site.com/photosets/123/photos (all the photos within photoset 123)

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date