Subdominios y rutas en Ruby on Rails
Freepik Illustration

En este artículo te voy a contar cómo podríamos resolver de manera muy sencilla el manejo de subdominios en una aplicación Ruby on Rails.

El problema

Imaginemos que desarrollamos una aplicación de venta de libros de recetas de “Cómo cocinar un pastel de papas”. Un delirio (delicioso) pero que nos sirve perfectamente para describir cómo manejar subdominios en una aplicación Rails.

Nuestro sistema es accedido a través de elmundodelapapa.com y queremos extender la aplicación para soportar múltiples subdominios (app.elmundodelapapa.com, api.elmundodelapapa.com, blog.elmundodelapapa.com). Todo utilizando una única aplicación y restringiendo el acceso a las rutas según el subdominio.

Definiendo las rutas

Una de las rutas que tenemos actualmente en la aplicación es la siguiente:

# config/routes.rb
get '/conaceitunas', to: 'pasteles#conaceitunas'

Esta ruta, definida de este modo, está disponible en todos los subdominios. Es decir, las requests a app.elmundodelapapa.com/conaceitunas y a api.elmundodelapapa.com/conaceitunas serán gestionadas por la misma ruta. Sin embargo, queremos que esta ruta esté disponible solo en el subdominio app.elmundodelapapa.com.

Para esto, podemos modificar nuestro archivo de rutas añadiendo un constraint:

get '/conaceitunas', 
to: 'pasteles#conaceitunas',
constraints: { subdomain: 'app' }

Esto va a restringir el acceso a app.elmundodelapapa.com/conaceitunas y cualquier request utilizando otro subdominio será rechazado.

Múltiples rutas

El helper constraints lo podemos usar en todas las rutas que necesitemos, solo es cuestión de repetirlo por cada línea:

get '/conaceitunas', 
to: 'pasteles#conaceitunas',
constraints: { subdomain: 'app' }
get '/carrito', to: 'cart#show', constraints: { subdomain: 'app' }
post '/carrito', to: 'cart#finish', constraints: { subdomain: 'app' }

El problema es que esto puede resultar tedioso y atentar contra la legibilidad del código, por lo que recomendaría definir un bloque constraints:

constraints 'app' do
get '/conaceitunas', to: 'pasteles#conaceitunas'
get '/carrito', to: 'cart#show'
post '/carrito', to: 'cart#finish'
end

Así podríamos definir rutas para todos nuestros subdominios:

constraints 'app' do
get '/conaceitunas', to: 'pasteles#conaceitunas'
get '/carrito', to: 'cart#show'
post '/carrito', to: 'cart#finish'
...
end

constraints 'blog' do
resources :posts
...
end

constraints 'api' do
resources :books, only: [:index]
...
end

Como habrás podido ver es muy sencillo manejar subdominios en nuestras aplicaciones Rails. En caso de que te hayas quedado con dudas, podés visitar la documentación oficial de Rails sobre rutas.

Solo te restaría configurar los registros DNS para que los subdominios apunten a la aplicación Rails, pero eso escapa al alcance de este artículo.

Gracias por llegar hasta acá! Dejame un aplauso si te gustó. Yo me voy a cocinar un pastel de papas porque me antojé 🤤.