O mesmo respond_to, um segundo formato
Todo broadcast do curso anterior disparou sem requisição nenhuma: um envio do servidor, sem ninguém pedir. O turbo stream deste curso responde a uma pergunta. O envio de um formulário comum, por HTTP comum, recebe a resposta do format.turbo_stream, um ramo do mesmo bloco respond_to que o Rails sempre usou para format.html e format.json.
O menor exemplo desta aplicação
app/controllers/locales_controller.rb, inteiro, sem edição:
class LocalesController < ApplicationController
def update
locale = params[:locale]
if I18n.available_locales.include?(locale.to_sym)
I18n.locale = locale.to_sym
session[:locale] = locale
end
respond_to do |format|
format.turbo_stream
format.html { redirect_back fallback_location: root_path }
end
end
end
Trocar o idioma do site é uma requisição PATCH para essa action. format.turbo_stream sem bloco quer dizer o mesmo que format.html queria no exemplo messages#create da documentação, visto no curso anterior: renderizar o template correspondente por convenção, aqui app/views/locales/update.turbo_stream.erb, e devolvê-lo com o content type certo.
O que decide qual ramo roda
A requisição do cliente traz um header Accept, e o respond_to escolhe o bloco de formato que bate com ele. Quando o Turbo envia um formulário com qualquer método que não seja GET, ele coloca text/vnd.turbo-stream.html na frente do text/html de sempre nesse header. Só que o seletor de idioma não é um formulário. Um controller Stimulus, o ui--locale-switch, manda o PATCH ele mesmo com fetch. Ele pede só text/vnd.turbo-stream.html e entrega a resposta ao Turbo.renderStreamMessage. Nos dois casos o cliente diz que entende streams, e o format.turbo_stream responde. Um cliente que nunca diz isso, como o curl, cai no format.html: o mesmo redirect_back que qualquer app Rails de antes do Hotwire rodaria.
Uma action, dois formatos de resposta
Nada na lógica do próprio LocalesController#update se importa com o ramo. Ler params[:locale], conferir se é válido e gravar a sessão acontecem uma vez, acima do bloco respond_to, igual para os dois. Só a resposta se divide: um template .turbo_stream.erb para um cliente, um redirect para o outro. O exemplo de format.turbo_stream do curso anterior mostrou a mesma ideia ao lado de format.json e format.html. O Rails escolher um template pelo formato que o cliente pede não é coisa do Hotwire. format.turbo_stream é só mais um ramo numa maquinaria que o Rails sempre teve.
Pontos-chave
format.turbo_streamdentro de umrespond_toé um mecanismo de requisição e resposta, e não um broadcast. Ele responde à requisição que o disparou, comoformat.htmleformat.jsonsempre fizeram.- O
LocalesController#updatedesta aplicação junta umformat.turbo_streamsem bloco (renderizalocales/update.turbo_stream.erbpor convenção) comformat.html { redirect_back ... }. - O header
Acceptdo cliente escolhe o ramo. Os envios de formulário do Turbo que não são GET e o seletor de idioma desta aplicação (umfetchno Stimulus) pedemtext/vnd.turbo-stream.html. Um cliente que nunca pede isso cai noformat.html. - A lógica do controller (validar e aplicar o idioma) roda uma vez, do mesmo jeito, antes de o ramo ser escolhido. Só o formato da resposta muda entre os dois.
Continue com a aula 2
Múltiplas ações, uma resposta
Um único POST de comentário devolve cinco ações de stream com alvo, rodadas no mesmo quadro de animação.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.