In a regular Rails 7 application, if you build an #index action that lists Tweets, and you want the user to be able to edit the tweets inline, you could do something like this:
# _tweet.html.erb
<%= turbo_frame_tag(tweet) do %>
<p><%= tweet.text %></p>
<%= link_to "Edit this tweet", edit_tweet_path(tweet) %>
<% end %>
And then in tweets/edit.html.erb
:
<%= turbo_frame_tag(tweet) do %>
<%= render "form", tweet: @tweet %>
<% end %>
Even tough it works, I’d like to prevent users from hitting the URL /tweets/1/edit directly, so that the edit.html.erb
is only accessible via the Turbo frame request.
However, these edit request (which is not a turbo_stream form submissions) is actually just a regular HTML request (it prints Processing by TweetsController#edit as HTML
in the console), so by doing this:
def edit
respond_to {|format| format.turbo_stream }
end
I can’t prevent users from accessing /tweets/1/edit directly, since it’s not a turbo stream.
In the good ol days of Rails UJS, this could be easily achieved by restricting the controller to respond to format.js
, like so:
def edit
respond_to {|format| format.js }
end
Or only providing a edit.js.erb
file in the views folder, because then HTML requests wouldn’t be served if the user requested /tweets/1/edit` directly (as it would be an HTML request).
Any way to achieve the same using Hotwire & Turbo?