Roteamento Rails de fora para dentro – parte 4
4 Rotas Regulares
Além do roteamento RESTful, Rails suporta roteamento regular – a forma para mapear URLs para controladores e ações. Com o roteamento regular, você não recebe a massas de rotas geradas automaticamente pelo roteamento RESTful. Em vez disso, você deve configurar cada rota dentro do seu aplicativo separadamente.
Enquanto o roteamento RESTful tornou-se o padrão Rails, ainda há muitos lugares onde o simples roteamento regular funciona perfeitamente. Você pode mesclar os dois estilos junto em uma única aplicação. Geralmente, você deve preferir o roteamento RESTful quando possível, por quê fará partes da sua aplicação serem escritas mais fáceis. Mas não é necessariamente tentar forçar cada última peça da sua aplicação dentro de um framework RESTful se isto não é um bom ajuste.
4.1 Parâmetros Obrigatórios
Quando você configurar uma rota regular,você fornece uma série de símbolos que o Rails mapeia partes de uma requisição HTTP de entrada. Dois desses símbolos são especiais: :controller mapeia para o nome do controlador na sua aplicação, e :action mapeia para o nome da ação do respectivo controlador. Por exemplo, considere uma rota Rails padrão:
map.connect ':controller/:action/:id' Se a requisição de entrada para /photos/show/1 é processada para esta rota (por quê não correspondeu com qualquer rota previamente no arquivo), então o resultado é que será invocado a ação show do controlador Photos, e construída com o parâmetro final (1) disponível como params[:id].
4.2 Componentes Coringas
Você pode configurar vários símbolos coringas junto com as rotas regulares como você quiser. Qualquer outra coisa diferente de :controller ou :action estará disponível para combinar a ação com a parte dos parâmetros da hash. Então, se você configurar rota como esta:
map.connect ':controller/:action/:id/:user_id' A chegada de uma URL de /photos/show/1/2 será despachada para a ação show do controlador Photos. params[:id] será definido para 1, e params[:user_id] será definido para 2.
4.3 Texto Estático
Você pode especificar um texto estático quando cria a rota. Neste caso, o texto estático é usado somente para combinar com as solicitações de entrada:
map.connect ':controller/:action/:id/with_user/:user_id' Esta rota deverá responder para URLs como /photos/show/1/with_user/2.
4.4 Querystring Parâmetros
O roteamento Rails automaticamente pega parâmetros de querystring e os torna disponíveis na hash params. Por exemplo, com esta rota:
map.connect ':controller/:action/:id' Solicitações de URL para /photos/show/1?user_id=2 será despachada para a ação show do controlador Photos. params[:id] será definido como 1, e params[:user_id] será definido como 2.
4.5 Definindo Padrões
Você não precisa explicitamente usar o símbolos :controller e :action juntamente com a rota. Você pode fornecer padrões para esses dois parâmetros em uma hash:
map.connect 'photo/:id', :controller => 'photos', :action => 'show' Com esta rota, chamadas URL para /photos/12 será despachado para a ação show juntamente para o controlador Photos.
Você pode definir outros padrões na rota fornecendo uma hash para a opção :defaults. Isto mesmo se aplica para os parâmetros que não estão explicitamente definidos em outros locais na rota. Por exemplo:
map.connect 'photo/:id', :controller => 'photos', :action => 'show', :defaults => { :format => 'jpg' } Com esta rota, solicitações URL para photos/12 serão despachado para a ação show juntamente para o controlador Photos, e o params[:format] será definido para jpg.
4.6 Rotas Nomeadas
Rotas regulares não precisa usar o método connect. Você pode usar qualquer outro nome para criar uma rota nomeada. Por exemplo,
map.logout '/logout', :controller => 'sessions', :action => 'destroy' Isto terá duas coisas. Primeiro, requisições para /logout serão enviadas para o método destroy do controlador Sessions. Segundo, Rails manterá os helpers logout_path e logout_url para usar nos seus códigos.
4.7 Requisitos de Rota
Você pode usar a opção :requirements para obrigar um formato para qualquer parâmetro na rota:
map.connect 'photo/:id', :controller => 'photos', :action => 'show', :requirements => { :id => /[A-Z]d{5}/ } Isso irá responder para URLs como /photo/A12345. Você pode expressar sucintamente a mesma rota desta forma:
map.connect 'photo/:id', :controller => 'photos', :action => 'show', :id => /[A-Z]d{5}/ 4.8 Condições na Rota
Condições na rota (introduzido com a opção :conditions) são projetados para implementar restrições nas rotas. Atualmente, somente a restrição suportada é :method.
map.connect 'photo/:id', :controller => 'photos', :action => 'show', :conditions => { :method => :get } Como nas condições em rotas RESTful, você pode especificar :get, :post, :put, :delete, ou :any para os métodos aceitáveis.
4.9 Englobamento de Rota
O englobamento de rota é a forma de especificar um parâmetro em particular (que deve ser o último parâmetro na rota) deverá combinar com todas as partes restantes da rota. Por exemplo
map.connect 'photo/*other', :controller => 'photos', :action => 'unknown', Esta rota deverá combinar com photo/12 ou /photo/long/path/to/12 igualmente, criando um array de caminhos como o valor params[:other]
4.10 Opções de Rotas
Você pode usar :with_options para simplificar a definindo grupos de rotas similares:
map.with_options :controller => 'photo' do |photo| photo.list '', :action => 'index' photo.delete ':id/delete', :action => 'delete' photo.edit ':id/edit', :action => 'edit' end A importância de map.with_options está declinando com a introdução de rotas RESTful.
5 Formatos e respond_to
Há mais de uma forma de roteamento que pode fazer coisas diferentes dependendo das diferenças nas solicitações HTTP: pela emissão de respostas que corresponde como a requisição específica será aceita. No roteamento Rails, você pode controlar isto em especial com o parâmetro :format na rota.
Por exemplo, considere o segundo padrão de rotas nos padrões do arquivo routes.rb:
map.connect ':controller/:action/:id.:format' Esta rota combina com requisições como /photo/edit/1.xml ou /photo/show/2.rss. Juntamente com o código apropriado, você pode diferenciar a resposta dependendo de como ela foi requisitada:
respond_to do |format| format.html # return the default template for HTML format.xml { render :xml => @photo.to_xml } end 5.1 Especificando o Formato com um cabeçalho HTTP
Se não houver o parâmetro :format na rota, o Rails automaticamente olhará para o cabeçalho HTTP Accept para determinar o formato desejado.
5.2 Reconhecendo tipos MIME
Por padrão, o Rails reconhece html, text, json, csv, xml, rss, atom, e yaml como tipos de respostas aceitáveis. Se você necessita de tipos por trás disso, você pode registrar isto no seu environment:
Mime::Type.register "image/jpg", :jpg 6 As Rotas Padrões
Quando você cria uma nova aplicação Rails, routes.rb é inicializado com essas duas rotas padrões:
map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' Essas rotas fornecem razoáveis padrões para muitas URLs, se você não está usando roteamento RESTful.
O padrão de rotas fará a cada ação para cada controlador na sua aplicação acessível por requisições GET. Se você conceber sua aplicação para fazer o uso consistente de RESTful e rotas nomeadas, você deve comentar as rotas padrões para prevenir o acesso de seus controladores através de verbos errados. Se você tiver as rotas padrões habilidades durante o desenvolvimento, embora, você precisa ter certeza de que não tenha involuntariamente dependente deles em algum lugar da sua aplicação – de outra forma você pode encontrar falhas misteriosas quando você desativá-las.
7 A Rota Vazia
Não confunda as rotas padrões com a rota vazia. A rota vazia tem uma finalidade específica: para requisitar os pedidos dentro da raiz do web site. Por exemplo, se seu site é example.com, então as requisições para http://example.com ou http://example.com/ serão tratadas pela rota vazia.
7.1 Usando map.root
A forma preferida de configurar uma rota vazia é com o comando map.root:
map.root :controller => "pages", :action => "main" O uso do método root fornece Rails que esta rota deve ser aplicada quando requisitado a raiz do site.
Para uma melhor legibilidade, você pode especificar uma rota já criada na chamada para map.root:
map.index :controller => "pages", :action => "main" map.root :index Por causa do processamento de cima para baixo do arquivo, a rota nomeada deve ser especificada antes da chamada para map.root.
7.2 Conectando uma String Vazia
Você pode especificar uma rota vazia explicitamente conectando uma string vazia:
map.connect '', :controller => "pages", :action => "main" Se a rota vazia não parece que está funcionando na sua aplicação, tenha certeza que você tenha deletado o arquivo public/index.html da sua árvore Rails.
8 Inspencionando e Testando Rotas
Roteando na sua aplicação não deve ser uma “caixa preta” que você nunca abrirá. O Rails oferece ferramentas prontas tanto para inspecionar e testas as rotas.
8.1 Vendo Rotas Existentes com Rake
Se você precisa de uma lista de todas as rotas disponíveis na sua aplicação, roda o comando rake routes. Irá descarregar todas as rotas para o console, na mesma ordem que aparecem em routes.rb. Para cada rota, você verá:
- O nome da rota (se houver)
- O verbo HTTP usado (se a rota não responder para todos os verbos)
- O padrão de URL
- Os parâmetros de roteamento que serão gerados pela URL
Por exemplo, aqui é uma pequena seção da saída do rake routes para uma rota RESTful:
users GET /users {:controller=>"users", :action=>"index"}
formatted_users GET /users.:format {:controller=>"users", :action=>"index"}
POST /users {:controller=>"users", :action=>"create"}
POST /users.:format {:controller=>"users", :action=>"create"}
Você verá que a saída de rake routes é muito mais legível se você aumentar a janela do terminal até que as linhas de saída não se enrolem
8.2 Testando Rotas
Rotas devem ser incluídas na sua estratégia de teste (assim como o resto da sua aplicação). Rails oferece três built-in assertions projetado para testar rotas mais simples:
- assert_generates
- assert_recognizes
- assert_routing
8.2.1 A Assertion The assert_generates
Use assert_generates para afirmar que um conjunto particular de opções gera um caminho particular. Você pode usar junto com as rotas padrões ou com rotas customizadas.
assert_generates "/photos/1", { :controller => "photos", :action => "show", :id => "1" } assert_generates "/about", :controller => "pages", :action => "about" 8.2.2 A Assertion assert_recognizes
A afirmação assert_recognizes é o inverso da assert_generates. Ela afirma ao Rails reconhecer os caminhos recebidos e as rotas para um local em particular na sua aplicação.
assert_recognizes { :controller => "photos", :action => "show", :id => "1" }, "/photos/1" Você pode fornecer o argumento :method para especificar um verbo HTTP:
assert_recognizes { :controller => "photos", :action => "create" }, { :path => "photos", :method => :post } Você também pode usar helpers RESTful para testar o reconhecimento da rota RESTful:
assert_recognizes new_photo_url, { :path => "photos", :method => :post } 8.2.3 A Assertion assert_routing
A afirmação assert_routing verifica a rota de duas formas: testa se o caminho gera as opções, e que as opções geram o caminho. Deste modo, combina as funções de assert_generates e assert_recognizes.
assert_routing { :path => "photos", :method => :post }, { :controller => "photos", :action => "create" }

