Aninhando um recurso: colocando uma relação de "pertence a" na URL
Onde o curso anterior de rotas parou
Rotas Rails: fundamentos, antes nesta série, mostrou resources :courses, param: :slug, only: [ :show ], o roteamento deste app para as páginas públicas de curso. Toda chamada resources daquele curso é um recurso único e isolado; nenhuma das sete aulas põe um bloco resources dentro de outro. Aquele curso cobriu a fundo a convenção de sete rotas numa linha e nunca chegou ao caso em que um recurso não existe sem outro.
Um Catalog::Lesson é esse tipo de recurso. Toda aula pertence a um curso, e o roteamento de admin deste app diz isso na própria URL.
A rota, no config/routes.rb deste app
namespace :admin do
namespace :catalog do
resources :courses do
resources :lessons, shallow: true do
# ...
end
end
end
end
Um bloco resources :lessons, escrito dentro do do ... end de resources :courses. O bin/rails routes mostra o que esse aninhamento produz para a ação create de uma aula:
admin_catalog_course_lessons POST /admin/catalog/courses/:course_id/lessons(.:format) admin/catalog/lessons#create
:course_id é um segmento de caminho novo que um resources :lessons isolado nunca geraria. Aninhar um recurso dentro de outro faz mais do que organizar o arquivo de rotas. Acrescenta o id do pai à URL, e o Rails entrega esse id ao controller como params[:course_id], que o Admin::Catalog::LessonsController#set_course lê:
def set_course
@course = Admin::Catalog::FindCourseQuery.call(id: params[:course_id]).course
end
Por que a URL diz isso
A ação create de uma aula precisa saber a que curso está acrescentando antes de fazer qualquer coisa. Dois recursos separados, resources :courses e resources :lessons declarados lado a lado, ainda funcionariam. A requisição poderia levar o id do curso de outro jeito, num campo oculto ou na sessão. O aninhamento põe essa exigência no formato da URL, onde ela fica visível, pode virar favorito e não dá para esquecer: /admin/catalog/courses/:course_id/lessons, não /admin/catalog/lessons. O banco registra a relação entre uma aula e seu curso (todo Catalog::Lesson tem uma chave estrangeira course_id), e as rotas ganham um formato equivalente.
O que este curso cobre
Sete aulas, cada uma conferida no config/routes.rb deste app, nos controllers e no código-fonte instalado do Rails. A aula 2 trata do shallow: true, que já está na linha resources :lessons deste app, e do que ele achata ou deixa aninhado. A aula 3 trata da palavra-chave singular resource, sem plural e sem :id, usada quatro vezes neste bloco de rotas. A aula 4 trata do member do ... end, que as rotas deste app usam duas vezes para uma ação reorder própria. A aula 5 trata de module: e scope module:, que levam uma URL a um controller num subdiretório. A aula 6 mostra que o shallow: true trata um recurso plural aninhado mais abaixo de um jeito e um singular de outro. A aula 7 segue uma rota aninhada da URL ao controller, juntando as aulas.
Continue com a aula 2
resources :lessons, shallow: true: o motivo do Rails para a opção
A documentação do Rails explica o shallow: true, que mantém index, new e create aninhados e achata ações de membro para :id.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.