Turbo stream trying to render into yield instead of turbo frame

128 views Asked by At

Trying to accomplish block unblock user functionality with Turbo in Rails 7. I am newbie, so please be patient with me.

<%= turbo_frame_tag "block_unblock_button" do %>
        <% if @is_blocked_by_current_user %>
          <%= link_to unblock_profile_path(@user), data: { turbo_method: :delete, turbo_frame: "block_unblock_button" },remote: true, class: "btn btn-outline-primary mb-1 col-6 d-md-block mx-auto" do %>
            Unblock
          <% end %>
        <% else %>
          <%= link_to block_profile_path(@user), data: { turbo_method: :post, turbo_frame: "block_unblock_button" },remote: true, class: "btn btn-outline-primary mb-1 col-6 d-md-block mx-auto" do %>
            Block
          <% end %>
        <% end %>
      <% end %>

This is my view that I need to replace with Turbo

resources :profiles do
    member do
      post 'block'
      delete 'unblock'
    end
  end

These are the routes

block.turbo_stream.erb

<%= turbo_stream.replace "block_unblock_button" do %>
  <%= link_to unblock_profile_path(@user), data: { turbo_method: :delete, turbo_frame: "block_unblock_button" }, remote: true, class: "btn btn-outline-primary mb-1 col-6 d-md-block mx-auto" do %>
    Unblock
  <% end %>
<% end %>

unblock.turbo_stream.erb

<%= turbo_stream.replace "block_unblock_button" do %>
  <%= link_to block_profile_path(@user), data: { turbo_method: :post, turbo_frame: "block_unblock_button" }, remote: true, class: "btn btn-outline-primary mb-1 col-6 d-md-block mx-auto" do %>
    Block
  <% end %>
<% end %>

Controller:

def block
    @user = User.find(params[:id])
    current_user.blocked_users.find_or_create_by(blocked_id: @user.id)
    @is_blocked_by_current_user = true

    respond_to do |format|
      format.turbo_stream
      format.html { redirect_to profile_path(params[:id]) }
    end
  end

  def unblock
    @user = User.find(params[:id])
    current_user.blocked_users.find_by(blocked_id: @user.id).destroy
    @is_blocked_by_current_user = false

    respond_to do |format|
      format.turbo_stream
      format.html { redirect_to profile_path(params[:id]) }
    end
  end

For example, when I click block, it sends POST with Turbo, 200ok response, button Unblock appears. When I am trying to click it, it sends Delete request with Turbo and I can click many times and it still sends Delete requests. When I inspect Elements tab in browser dev tools, I noticed it's trying to insert my frame inside of my layout, in place of yield, here is a screen:

I would type it, but it desappears

For example, when I click block, it sends POST with Turbo, 200ok response, button Unblock appears. When I am trying to click it, it sends Delete request with Turbo and I can click many times and it still sends Delete requests. When I inspect Elements tab in browser dev tools, I noticed it's trying to insert my frame inside of my layout, in place of yield, here is a screen:

I would type it, but it desappears

Ideally turbo stream should insert correct button in turboframe, but it doesn't.

1

There are 1 answers

0
Alex On BEST ANSWER

You have some extra code that is unnecessary:

# no need for turbo frame
<%= turbo_frame_tag "block_unblock_button" do %>

# even with the turbo frame, you don't have to specify it if link is inside the frame
turbo_frame: "block_unblock_button"

# this does nothing
remote: true

<div id="block_unblock_button">
  <% if @is_blocked_by_current_user %>
    <%= link_to "Unblock", unblock_profile_path(@user), data: {turbo_method: :delete} %>
  <% else %>
    <%= link_to "Block", block_profile_path(@user), data: {turbo_method: :post} %>
  <% end %>
</div>

You don't want to replace, you want to update the contents:
https://stackoverflow.com/a/73395858/207090

# block.turbo_stream.erb

<%= turbo_stream.update "block_unblock_button" do %>
  <%= link_to "Unblock", unblock_profile_path(@user), data: {turbo_method: :delete} %>
<% end %>
# unblock.turbo_stream.erb

<%= turbo_stream.update "block_unblock_button" do %>
  <%= link_to "Block", block_profile_path(@user), data: {turbo_method: :post} %>
<% end %>