Aninhando um recurso: colocando uma relação de "pertence a" na URL

Prévia grátis 3 min de leitura

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.

Aula 1 de 7 · grátis

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.

Digite para buscar...