Continuando con el post anterior. Cuando RESTful parece no alcanzar y cuando nuestros recursos empiezan a tener hijos necesitamos de los recursos anidados (nested resources). Aquí usaremos los mismos ejemplos de [1].
Suponemos que tenemos una tabla revistas (magazines) y cada revista a su vez tiene publicidades (ads). Tendríamos los modelos:
class Magazine < ActiveRecord::Base has_many :ads end class Ad < ActiveRecord::Base belongs_to :magazine end
En routes.rb configuramos:
map.resources :magazines do |magazine| magazine.resources :ads end # o la versión corta: # map.resources :magazines, :has_many => :ads.
Tendremos como resultado, las siguientes rutas:
| Verb | URL | controller | action | used for |
|---|---|---|---|---|
| GET | /magazines/1/ads | Ads | index | display a list of all ads for a specific magazine |
| GET | /magazines/1/ads/new | Ads | new | return an HTML form for creating a new ad belonging to a specific magazine |
| POST | /magazines/1/ads | Ads | create | create a new ad belonging to a specific magazine |
| GET | /magazines/1/ads/1 | Ads | show | display a specific ad belonging to a specific magazine |
| GET | /magazines/1/ads/1/edit | Ads | edit | return an HTML form for editing an ad belonging to a specific magazine |
| PUT | /magazines/1/ads/1 | Ads | update | update a specific ad belonging to a specific magazine |
| DELETE | /magazines/1/ads/1 | Ads | destroy | delete a specific ad belonging to a specific magazine |
Que en hacen uso de las acciones: index, new, create, show, edit, update y destroy. Pero todas haciendo referencia a una magazine que la contiene. También nos genera los helpers: magazine_ads_url, edit_magazine_ad_path, etc.
¿Cómo viajan los parámetros? Si ingresamos una URL: magazines/1/ads2 tendríamos un:
params = {"magazine_id"=>"1", "action"=>"show", "id"=>"2", "controller"=>"ads"}
Otra forma de generar los links (en un link_to) es con arreglos:
<%= link_to "Ad details", magazine_ad_path(@magazine, @ad) %># un link a show
También podemos usar :name_prefix para configurar un poco más nuestras rutas anidadas:
1) Cambiarle el nombre
map.resources :magazines do |magazine| magazine.resources :ads, :name_prefix => 'periodical' end
2) Ocultar el prefijo:
map.resources :magazines do |magazine| magazine.resources :ads, :name_prefix => nil end
nota: en este último caso necesitaremos pasar por parámetros el id del magazine en los helpers: ads_url(@magazine) y edit_ad_path(@magazine, @ad).
Resources únicos:
map.resources :photos do |photo| photo.resource :photographer end # o la forma corta: # map.resources :photos, :has_one => :photographer
Por último, cuando queremos crear un nuevo elemento, ¿Cómo armamos el formulario? pues con:
<% form_for([ @magazine, @ad ]) do |f| %>

