Search code examples
ruby-on-railsrubybroadcast

real time broadcasting in not working in rails 7


I have added broadcasting in the rails model, please have a look at the below files .

Comment model

class Comment < ApplicationRecord

  validates :body, presence: true
  belongs_to :post
  after_create_commit { broadcast_append_to "comments_#{self.post_id}", partial: "posts/comment" }

end

Post model

class Post < ApplicationRecord

  has_many :comments, dependent: :destroy

end

app/views/posts/index.html.erb

<h1 class="text-center m-4 text-success">Posts</h1>
<div id="posts">
    <div class="row">
        <% @posts.each do |post| %>
            <%= render post %>
        <% end %>
    </div>
</div>

app/views/posts/_post.html.erb

<div class="col-lg-4 mb-2">
    <div class="card border-0" style="width: 18rem;">
        <div class="card-body">
            <p>
                <span class="comment">
                    <%= link_to fa_icon("comment"),"#", data: { action: "click->like#comment",comment_url: new_post_comment_path(post.id) } %>
                </span>
            </p>
            <div id="add_comment_<%= post.id %>"></div>
            <h5 class="card-title"><%= post.title %></h5>
            <p class="card-text"><%= post.description %></p>
            <strong>Comments</strong>
            <%= turbo_stream_from "comments_#{post.id}" %>
            <%= turbo_frame_tag "comments_#{post.id}" do %>
                <div id="add_comments_<%= post.id %>">
                    <% post.comments.each do |comment_post| %>
                        <%= render partial: "posts/comment", locals: { comment: comment_post } %>
                    <% end %>
                </div>
            <% end %>
        </div>
    </div>
</div>

app/views/posts/_comment.html.erb

<p id="comment_<%= comment.id %>" data-controller="comment"><%= comment.body %>
    &nbsp;
    <span>
        <%= link_to "edit",post_comment_edit_path(comment.post,comment), data: { turbo_method: :post }  %>
    </span>
    &nbsp;
    <span><%= link_to "delete", post_comment_path(comment.post,comment), data: { turbo_method: :delete } %></span>
    &nbsp;
    <span><%= commentUpdatedAt(comment) %> ago</span>
</p>

I have checked with binding.pry, in the comment model does not get post_id when creating a comment, so the targets are different.

Please help me


Solution

  • I have found the above answer,

    app/models/comment.rb file

    class Comment < ApplicationRecord
    
      validates :body, presence: true
      belongs_to :post
      belongs_to :user
      
      after_create_commit :set_comment
      after_update_commit :update_comment
      after_destroy_commit :destroy_comment
    
      private
    
      def set_comment
        broadcast_append_to "add_comments_#{self.post.id}", partial: "posts/comment", target: "add_comments_#{self.post.id}"
      end
    
      def update_comment
        broadcast_update_to "comment_#{self.id}", partial: "posts/comment", target: "comment_#{self.id}"
      end
    
      def destroy_comment
        broadcast_remove_to "comment_#{self.id}"
      end
      
    
    end
    

    app/views/posts/_post.html.erb file

    <strong>Comments</strong>
                <%= turbo_stream_from "add_comments_#{post.id}" %>
                <div id="add_comments_<%= post.id %>">
                    <% post.comments.each do |comment_post| %>
                        <%= render partial: "posts/comment", locals: { comment: comment_post } %>
                    <% end %>
                </div>
    

    app/views/posts/_comment.html.erb file

    <%= turbo_stream_from "comment_#{comment.id}" %>
    <p id="comment_<%= comment.id %>" data-controller="comment"><%= comment.body %>
        &nbsp;
        <span>
            <%= link_to "edit",post_comment_edit_path(comment.post,comment), data: { turbo_method: :post }  %>
        </span>
        &nbsp;
        <span><%= link_to "delete", post_comment_path(comment.post,comment), data: { turbo_method: :delete } %></span>
        &nbsp;
        <span>
            <%= link_to "reply",replyComment_post_comment_index_path(comment.post), data: { turbo_method: :post }  %>
        </span>&nbsp;
        <span><%= commentUpdatedAt(comment) %> ago</span>
    </p>
    

    The solution is working well as I expected.