Rails Routing Constraints
title: “Constraints de roteamento no Rails” date: 2021-04-05 09:00:20 +0300 categories: rails routing tags: rails routing constraints —-
Quando usar routing constraints no Rails
Constraints permitem ao roteador decidir para onde enviar a request sem empurrar a lógica para controllers. Útil para roteamento por subdomínio, home diferente para guest/logado, controle de formato e proxys.
Abordagem base (controller)
Você pode redirecionar no controller, mas o router continua fazendo trabalho extra:
1
2
3
4
5
6
7
8
9
10
11
12
# app/controllers/home_controller.rb
class HomeController < ApplicationController
before_action :redirect_to_dashboard_if_signed_in
def index; end
private
def redirect_to_dashboard_if_signed_in
redirect_to dashboard_path if signed_in?
end
end
1
2
3
4
5
# config/routes.rb
Rails.application.routes.draw do
resource :dashboard, only: [:index]
resource :home, only: [:index]
end
Use routing constraints
Mantenha decisões em routes.rb. Padrões comuns:
-
Constraint por segmento
1 2
match '/:year/:month/:day' => 'info#about', constraints: { year: /\d{4}/, month: /\d{2}/, day: /\d{2}/ }
-
Constraint por request (User-Agent, subdomínio, formato)
1 2
match '/:year/:month/:day' => 'info#about', constraints: { user_agent: /Firefox/ }
-
Constraint dinâmica (lambda ou classe)
- Lambda:
1 2
get '*path', to: 'proxy#index', constraints: ->(req) { req.env['SERVER_NAME'].match?('foo.bar') }
- Class: ```ruby constraints Subdomain do get ‘*path’, to: ‘proxy#index’ end
- Lambda:
class Subdomain def self.matches?(request) request.subdomain.present? && request.subdomain.start_with?(‘foobar’) end end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
### Exemplo: home para guest vs logado
```ruby
# lib/signed_in_home.rb
class SignedInHome
def self.matches?(request)
request.cookies['remember_token'].present?
end
end
# config/routes.rb
Rails.application.routes.draw do
constraints SignedInHome do
root to: 'dashboard#show', as: :dashboard
end
root to: 'home#show'
end
Aqui o router decide qual root servir antes de chegar ao controller. Troque a lógica do cookie pelo seu mecanismo de auth (ex.: Warden, JWT etc.).
Nota: há 2 rotas para root, uma dentro do constraint e outra fora. A ordem importa.
Referências
-
Thoughbot Clearance gem e
Clearance::Constraints::SignedIn. - Documentação do Rails sobre Routing.