Lidando com URLs no Rails


Leia em 1 minuto

Quando você começa a lidar com links/URLs no Rails, a tarefa pode se tornar chata muito rapidamente, principalmente por causa dos símbolos :controller e :action. Uma maneira de contornar este problema é utilizar Named Routes.

Ao invés de ter que explicitar o controller e a action toda vez, você pode dar um nome à sua rota e acessá-la como um método route_name_url ou route_name_path, onde route_name é o nome que você escolheu. A diferença entre _url e _path é que o primeiro método retorna a URL completa, incluindo o protocolo e domínio; já o segundo método retorna apenas o caminho relativo ao recurso que você quer acessar. Para utilizar esta funcionalidade, basta você definir um nome ao invés de utilizar map.connect.

ActionController::Routing::Routes.draw do |map|
  map.home '/', :controller => 'pages', :action => 'home'
  #...
end

Neste exemplo, nossa URL estaria disponível através dos métodos home_url e home_path.

Quando é necessário acessar partes da URL como parâmetros, a coisa ainda fica fácil.

ActionController::Routing::Routes.draw do |map|
  map.archives '/blog/archives/:year/:month/:day',
      :controller => 'posts',
      :action => 'archives',
      :requirements => {
          :year => /[0-9]{4}/,
          :month => /[0-9]{1,2}/,
          :day => /[0-9]{1,2}/
      }

  #...
end

Uma rota como a que definimos acima poderia ser facilmente utilizada de duas formas: passando os parâmetros na sequência em que são explicitados na URL ou como um hash.

#passando os parâmetros sequencialmente
redirect_to archives_url(2007, 5, 1)
redirect_to archives_url(2007, 5)
redirect_to archives_url(2007)

#passando os parâmetros em um hash
redirect_to archives_url(:day => 1, :month => 5, :year => 2007)
redirect_to archives_url(:month => 5, :year => 2007)
redirect_to archives_url(:year => 2007)

Você pode até criar algo mais genérico, passando os parâmetros que forem necessários. Por exemplo, veja como poderia ser definida a rota para uma área administrativa.

ActionController::Routing::Routes.draw do |map|
  map.admin '/admin/:controller/:action/:id'
  #...
end

E para acessar esta url, bastaria fazer uma chamada como admin_url(:controller => 'payments').

À partir da versão 1.2, você pode utilizar o map juntamente com o método with_options o que torna muito interessante a maneira como definimos diversas rotas de um único controller, por exemplo.

ActionController::Routing::Routes.draw do |map|
  map.with_options :controller => 'pages' do |p|
    p.home '/', :action => 'home'
    p.tools '/tools', :action => 'tools'
    p.contact '/contact', :action => 'contact'
    p.terms '/terms', :action => 'terms'
  end

  #...
end

Particularmente, estou usando "Named Routes" sempre que posso, e cá entre nós. Ficou muito mais fácil de entender o código.