Nested frame and stream

Hello, I have multiple posts, each can have multiple comments, and I have a “messages” stream:

<%= turbo_stream_from "posts" %>

<%= turbo_frame_tag "posts" do %>
  <%= render @posts %>
<% end %>

Inside the “post” partial, the post frame display the post without problem:

  <%= turbo_frame_tag post do %>
    <p><%= post.body %></p>
  <% end %>
  
  <%= turbo_stream_from "comments" %>
  <%= turbo_frame_tag dom_id(post) do %>
      <%= render post.comments %>
  <% end %>

But I have a problem with the “comments” section.
When I create a comment, if I have 10 post, the message is displayed 10 time inside the same message.

I think it’s because the “comments” stream use the same name/ID inside each post, but if I change the ID, the content cannot be broadcasted by the configuration used inside the model:

How can I fix this problem please?
Thanks.

1 Like

I ran into the same issue just a couple of hours ago. You can actually specify a “target” option for the broadcast methods.

class Comment < ApplicationRecord
  belongs_to :post
  # "comments" is the name of the ActionCable channel
  # target specifies which turbo frame you want to append the comments to
  # in your case it will be the dom_id of the post
  after_create_commit { broadcast_prepend_to "comments", target: post }
  after_update_commit { broadcast_replace_to "comments" }
end

That way the comments will be broadcasted using the “comments” channel and will be appended to the turbo_frame with the dom_id of the post. If you omit the target parameter, rails will look for a turbo-frame with the dom_id of the comment itself (e.g. “comment_10”) so make sure that you have a matching turbo-frame in your comments ERB partial.

Thanks, but this solution doesn’t work for me, the comment is added after the div#post_id and not after the comments list inside div#post_id.

You can see the broadcasting log here:

[ActionCable] Broadcasting to comments: "<turbo-stream action="append" target="post_156"><turbo-frame id="comment_174">\n …

Can you share the comments partial as well? What ID does the comment list inside your div#post_id have?

Work with:

after_create_commit { broadcast_prepend_to 'comment', target: post }
Insted of:
after_create_commit { broadcast_prepend_to 'comments', target: post }

But… Use prepend, append or replace here has the same effect and add the comment without problem, but a #post_175 is added inside #post_175 everytime I add a new comment:

Capture d’écran 2021-01-22 à 12.45.22

Try

after_create_commit { broadcast_append_to "post_#{self.post.id}_comments", target: "post_#{self.post.id}_comments" }

in your comment.rb and change your turbo_frame/stream_from respectively

1 Like

This is the solution but the comment counter inside the parent post is not updated.