Rails y Turbo/Hotwire: Evitar que el usuario acceda directamente a la vista
En una aplicación de Rails 7 regular, si se construye una acción #index que lista Tweets y se desea que el usuario pueda editar los tweets en línea, se podría hacer algo como esto:
<h1>_tweet.html.erb</h1>
<%= turbo_frame_tag(tweet) do %>
<%= tweet.text %>
<%= link_to "Editar tweet", edit_tweet_path(tweet) %>
<% end %>
Y luego en tweets/edit.html.erb:
<%= turbo_frame_tag(tweet) do %>
<%= render "form", tweet: @tweet %>
<% end %>
Aunque funcione, me gustaría evitar que los usuarios accedan directamente a la URL /tweets/1/edit, de modo que edit.html.erb solo sea accesible a través de la solicitud Turbo frame.
Sin embargo, esta solicitud de edición (que no es una presentación de formulario de turbo_stream) es en realidad solo una solicitud HTML regular (imprime “Processing by TweetsController#edit as HTML” en la consola), por lo que al hacer esto:
def edit
respond_to {|format| format.turbo_stream }
end
No puedo evitar que los usuarios accedan directamente a /tweets/1/edit, ya que no es un turbo stream.
En los buenos tiempos de Rails UJS, esto se podía lograr fácilmente restringiendo el controlador para que responda a “format.js”, así:
def edit
respond_to {|format| format.js }
end
O solo proporcionando un archivo edit.js.erb en la carpeta de vistas, porque entonces las solicitudes HTML no se servirían si el usuario solicitara /tweets/1/edit directamente (ya que sería una solicitud HTML).
¿Hay alguna manera de lograr lo mismo utilizando Hotwire y Turbo?
davy.ai
Sí, hay una forma de lograr lo mismo utilizando Hotwire y Turbo. En lugar de usar
format.turbo_stream
en la acciónedit
, podemos usarformat.turbo_stream.html
para especificar que la respuesta solo debe ser accesible a través de Turbo frames.Aquí está el código actualizado:
Esto restringirá el acceso a la acción
edit
solo a Turbo frames, evitando que los usuarios accedan directamente a través de la URL.