How to update independent pieces of a web page with turbo frames and turbo streams in ruby on rails

40 views Asked by At
  • Am building a blog post and i have a model named comments, i have used the same model also for replies .

comment.rb

class Comment < ApplicationRecord
  

  include ActionView::Helpers
  belongs_to :post
  belongs_to :user

  has_many :likes, as: :likeable
  scope :ordered, -> { order(id: :desc) }
  belongs_to  :parent, class_name: 'Comment', optional: true
  has_many    :replies, class_name: 'Comment', foreign_key: :parent_id, dependent: :destroy
  has_many :notifications, dependent: :destroy
  validates :body, presence: true

  after_create_commit :broadcast_later

  private

  def broadcast_later
    if parent_id.nil?
      broadcast_prepend_later_to(
        'comments_list',
        partial: 'comments/comment',
        locals: { comment: self, user: user }
      )
    else
      broadcast_after_to(
        'comments_list',
        partial: 'comments/comment',
        locals: { comment: parent, user: user },
        target: dom_id(parent)
      )
    end
  end
end
  • Below is my comments partial.
<%= turbo_frame_tag comment do%>
  <div class="">
    <div class="p-4 rounded-lg border-2 border-gray-200 my-4">
      <div class="flex items-center justify-between">
        <span class="flex items-center">
          <p class="inline-flex items-center mr-3 text-sm text-gray-900 dark:text-white font-semibold">
            <img class="mr-2 w-6 h-6 rounded-full" src="https://flowbite.com/docs/images/people/profile-picture-2.jpg" alt="Michael Gough">
            Michael Gough
          </p>
          <p class="text-sm text-gray-600 dark:text-gray-400">
            <time pubdate datetime="2022-02-08" title="February 8th, 2022">Feb. 8, 2022</time>
          </p>
        </span>
      </div>
      <p class="mt-4 text-gray-500 dark:text-gray-400"><%= comment.body %></p>
    </div>
    <%= turbo_frame_tag Comment.new do%>
      <%= render "comments/like_button", comment: comment, user: comment.user%>
    <% end %>
    <% if comment.replies.any? %>
      <% comment.replies.each do |reply| %>
        <div class="ml-4">
          <%= render 'comments/comment', comment: reply, user: reply.user %>
        <% end %>
      <% end %>
    </div>
  <% end %>
  • am rendering comments recursively using the same comments partial.
  • below is my comments/create_turbo_stream.erb
<%= turbo_stream.replace dom_id(Comment.new) do%>
  <%= render partial: "comments/like_button", locals: { comment: @comment, user: @comment.user }%>
<% end %>
<% if @comment.parent_id.nil? %>
  <%= turbo_stream.prepend "comments" do %>
    <%= render @comment%>
  <% end %>
<% else %>
  <%= turbo_stream.after dom_id(@comment.parent) do %>
    <div class="ml-4">
      <%= render @comment%>
    </div>
  <% end %>
<% end %>

  • Below is my post show page where am displaying a post with all its comments below.
  <div>
    <%= turbo_stream_from "comments_list"%>
    <%= turbo_frame_tag "comments" do%>
      <%= render @comments%>
    <% end %>
  </div>
  • The problem is when i create a child comment, it renders a parent nested with its child two times as seen in this screen shot. any one with an idea on how i properly get them nested after broadcasting.
  • I want it to be nested once not two times, its like their is double rendering somewhere after broadcasting

enter image description here

  • Any help will be appreciated!
0

There are 0 answers