segunda-feira, 12 de novembro de 2012

Roteamento de Resources em Rails

Rails Routing, traduzindo e explicando, é a forma como o framework Rails infere a rota até a ação de um controlador através da URL no browser e do método HTTP (GET, POST, PUT ou DELETE).
Conforme já mencionei no post sobre múltiplos bancos de dados, o Rails segue o padrão de convention over configuration. As convenções assumidas para o roteamento vão servir para a grande maioria dos casos, mas customizar o roteamento em sua aplicação é fácil e extremamente flexível.

Resources



O padrão do Rails é trabalhar com resources (recursos, em português). Se você possui uma entidade Pessoa, por exemplo, existirá uma tabela no banco de dados chamada pessoas, um modelo em app/models chamado Pessoa, um controlador em app/controllers chamado PessoasController e um roteamento no arquivo config/routes.rb declarando a seguinte linha:

resources :pessoas

Com sua aplicação estruturada dessa forma, o roteamento será feito conforme abaixo:


Método HTTP  URL Ação Finalidade
GET /pessoas index Lista de pessoas
GET /pessoas/new new Formulário para cadastrar nova Pessoa
POST /pessoas create Envio de dados de nova Pessoa
GET /pessoas/:id show Apresentação de dados de determinada Pessoa  
GET /pessoas/:id/edit   edit Formulário para edição de dados de Pessoa
PUT /pessoas/:id update Envio de novos dados de Pessoa
DELETE /pessoas/:id destroy   Exclusão de Pessoa


E automaticamente ficarão disponíveis helpers para acesso a esses caminhos (paths) a partir de qualquer view. Os helpers farão com que o link exato seja renderizado na sua página, mantendo assim seu código mais limpo e automatizado.

URL Ação Helper
/pessoas index pessoas_path
/pessoas/new new new_pessoa_path
/pessoas/:id show      pessoa_path(:id) ou pessoa_path(7)
/pessoas/:id/edit      edit edit_pessoa_path(:id) ou edit_pessoa_path(7)     


O motivo de os paths serem quatro em vez de sete (total de rotas) é que três das rotas servem para ações entre a aplicação e o framework (POST, PUT e DELETE) e não são acionadas diretamente pelo usuário (através de um link).

E se você quiser a URL inteira (com domínio e porta) basta usar "_url" em vez de "_path" como sufixo do helper.


Namespaces



Se a quantidade de controladores no diretório app/controllers começa a ficar demais, ou por simples motivo de organização, pode ser interessante agrupar alguns controladores em um sub-diretório, como app/controllers/admin.

Para organizar dessa forma, há três passos:
  • Definir a classe do seu controlador dentro de um namespace, como Admin::UsuariosController
  • Mover a classe para um novo diretório com o mesmo nome do namespace: app/controllers/admin
  • Alterar o roteamento conforme abaixo:


namespace :admin do
  resources :usuarios
end


O roteamento configurado dessa forma fará com que o path de acesso também seja como /admin/usuarios.
Se você quiser somente organizar os diretórios e manter isso transparente ao path de forma que o controlador continue sendo acessado por /usuarios, o roteamento deverá ser configurado dessa forma:

scope :module => "admin" do
  resources :usuarios
end

Ou dessa forma em uma única linha:

resources :usuarios, :module => "admin"


Se, ao contrário, você quiser que somente o path seja /admin/usuarios, e o controlador de usuários esteja no diretório padrão app/controllers, o roteamento deve ser assim:

scope "/admin" do
  resources :usuarios
end

Ou em uma única linha:
resources :posts, :path => "/admin/usuarios"



Resources aninhados



Resources aninhados, ou nested resources, são úteis quando um resource só existe dentro do contexto de outro resource, como o conceito de composição da UML.

Um bom exemplo seria dois modelos Livro e Capitulo. Capítulos só existem dentro de livros, então acessar o path /livros/3/capitulos/7 pode fazer mais sentido do que ter um path direto /capitulos/7. O roteamento deveria ser feito então assim:

resource :livros do
  resources :capitulos
end


O aninhamento de resources pode ser feito em vários níveis, mas mais do que um subnível não é recomendado.

Concluindo



Há muitos outros detalhes sobre roteamento envolvendo a customização inteira de um path, definição da página raiz, entre outras muitas possibilidades. Recomendo a referência oficial disponível em http://guides.rubyonrails.org/routing.html. Tem uma referência em português também, http://guias.rubyonrails.com.br/, mas que no momento em que escrevo está desatualizada, referenciando a versão 2.3 do Rails.
Também o livro Rails Recipes possui algumas boas receitas sobre roteamento.


Até a próxima!

Nenhum comentário:

Postar um comentário