_posts.html.erb
<div class="container col-sm-4 mx-auto mt-4">
<% posts.each do |post| %>
<%= turbo_frame_tag dom_id(post) do %>
<div class="card text-center bg-info" style="width: 18rem;">
<%= image_tag file_path(post.medias.first), class: "rounded mx-auto d-block" %>
<h6 class="card-subtitle mb-2 text-body-secondary mt-2">by <%= post.user.first_name %> <%= post.user.last_name%> </h6>
<div class="card-body">
<p class="card-text"><%= post.description %></p>
<%= link_to "View Post", post_path(post), class: "btn btn-dark" %>
</div>
<div class="card-footer text-body-secondary">
<%= time_ago_in_words(post.created_at) %> ago
</div>
<div class="row justify-content-between mb-2">
<% if current_user_post_like?(post) %>
<div class="col-sm-3">
<%= post.likes.count %>
<%= link_to "Unlike", likes_path({id: post}), data: {turbo_stream: true, turbo_method: :delete} %>
</div>
<% else %>
<div class="col-sm-3">
<%= post.likes.count %>
<%= link_to "Liked", likes_path({id: post}), data: {turbo_stream: true, turbo_method: :post} %>
</div>
<% end %>
<div class="col-sm-3"> 1 </div>
<div class="col-sm-3"> 1 </div>
</div>
</div>
<% end %>
<% end %>
</div>
likes_controller.rb
class LikesController < ApplicationController
before_action :fetch_post
def create
@like = Like.find_or_initialize_by(likeable: fetch_post, user: current_user)
if @like.save
@posts = Post.all
render turbo_stream: turbo_stream.replace(
@post,
partial: 'shared/posts',
locals: { posts: @posts }
)
end
end
def destroy
@like = current_user.likes.find_by(likeable: @post)
if @like.destroy
@posts = Post.all
render turbo_stream: turbo_stream.replace(
@post,
partial: 'shared/posts',
locals: { posts: @posts }
)
end
end
private
def like_params
params.require
end
def fetch_post
@post = Post.find_by(id: params[:id])
end
end
pages_controller.rb
class PagesController \< ApplicationController
def index
@posts = Post.all
end
end
I am getting error while render partial with turbo_stream , designs are getting broken, duplicates posts are showing. i am fetching all posts in pages controllers and rendering the _posts partial after that when i clicked on like it should get update with turbo_stream enter image description here
You're replacing one target post with all posts including the container, which ends up nesting and duplicating everything.
# app/views/shared/_posts.html.erb -->
<%= render @posts %>
I'm not sure if you actually need turbo frame here, it's not required for this:
# app/views/posts/_post.html.erb
# this is your target that you want to replace
# vvvvvvvvvvvv
<%= tag.div id: dom_id(post) do %>
# TODO: your post layout
<% end %>
Then in your controller, when you're replacing a post you have to render just that post:
render turbo_stream: turbo_stream.replace(
@post, # this implicitly generates target id with `dom_id(@post)`
partial: "posts/post", # which is replaced with this partial
locals: {post: @post}
)
# can be shortened to
render turbo_stream: turbo_stream.replace(@post)
Another similar example: https://stackoverflow.com/a/74508675/207090