Anidamiento de recursos con REST en Ruby on Rails ó cómo acceder de dos maneras distintas a un mismo controlador utilizando REST con Ruby On Rails.

Después de un título tan largo, lo primero es meter en situación. Tengo una web que tiene temas, en cada tema hay más temas y descargas. Estos se muestran con los controladores topics y downloads respectivamente. El problema venía puesto que los controladores se tenían que poder acceder de dos formas. En el caso de las descargas:

1.- /downloads
2.- /topics/:topic_id/downloads

En el caso de los temas:

1.- /topics
2.- /topics/:topic_id/topics

Aproximación: Crear un segundo controlador.

Empecemos por el tema de los temas y sus subtemas. En este caso utilizaremos un segundo controlador al que llamaremos subtopic. Para poder acceder de la forma buscada hay que sustituir en el archivo config/routes.rb la línea

map.resources :topics
por lo siguiente:

map.resources :topics do |topic|
topic.resources :subtopics, :path_prefix => "topics/:topic_id"
end

Después, se eliminan los métodos delete, edit, show y update, pues sólo se necesitan los métodos create, index y new. Además, lo más lógico sería implementar los métodos create, index y new de forma que podamos aprovechar las vistas del controlador topic. Aún así, tenemos repetición, lo que viola el principio DRY que rige a Rails. Por lo tanto, veamos cómo podemos conseguir el resultado obtenido de una forma más sencilla y elegante.

Fase final: las cosas bien hechas.

En este caso cogeremos como ejemplo las descargas de un tema. Para ello, al igual que en el ejemplo anterior, hay que modificar el routes.rb añadiéndole las siguientes líneas

map.resources :topics do |topic|
topic.resources :downloads, :path_prefix => "topics/:topic_id", :name_prefix => 'topic_'
end

map.resources :downloads

Hay que recalcar dos aspectos de estas rutas. En primer lugar, el :name_prefix. De esta forma, podremos diferenciar entre si hay que crear un path del tipo /downloads/1 o del tipo /topics/:topic_id/downloads simplemente precediendo el nombre de los métodos que construyen el path con topic_. Es decir, si utilizamos el método edit_download_path(download) obtenemos la ruta http://localhost:3000/downloads/2;edit. En cambio, al utilizar el método topic_edit_download_path(download.topic,download) (hay que recalcar que el :name_prefix va antes del nombre normal del método y que los parámetros se pasan según el orden en el que se encuentran en la ruta) obtenemos la ruta http://localhost:3000/topics/1/downloads/2;edit.
Espero que este artículo os haya sido tan interesante (aunque me exprese como el culo) como para mí fue el investigar cómo se hace esta monería con REST, Ruby y Ruby on Rails.

Author: Serabe

Mathematician, and Ruby and JavaScript programmer. Sometimes I speak at conferences and local meetups.

1 thought on “Anidamiento de recursos con REST en Ruby on Rails ó cómo acceder de dos maneras distintas a un mismo controlador utilizando REST con Ruby On Rails.”

  1. Cómo me gustaría ser capaz de entender tus posts.
    Me habré equivocado de rama? Igual me van más las humanidades.

    Besos y prometo comentar más 🙂

    Ánimos hermanito

Leave a Reply

Your email address will not be published. Required fields are marked *