Now that we have moved the likes logic into our partial, we can move ahead with implementing turbo. This enables us to see the changes real time on click without reloading the entire page. This makes the app user friendly.
We will be adding id to the parent div
in _likes.html.erb
. Let's name the id post_id_container
. In order to make it unique, we can replace the id
with actual post id. This will make the code look like:
<div class="px-2" id="post_<%= post.id %>_container">
After this, we can tell our link_to tag to replace the content of this particular id when clicked. We can do this by adding properties to the data attribute as below:
<%= link_to post_upvotes_path(post.id), data: { turbo_method: :post, turbo_frame: "post_#{post.id}_container" } do %>
Let's take a moment to understand this. We have a turbo frame with id as post_id_container
. When the link is clicked, a turbo request is sent to the backend. With response from the backend, the link knows which frame to replace. So, after receiving the response, turbo will smartly replace only the likes portion of the browser with newly rendered HTML code.
In order to achieve the new data and HTML, we need to tell our create method in the controller to return few things.
We will need:
This will make our code like below:
respond_to do |format|
format.turbo_stream { render turbo_stream: turbo_stream.replace("post_#{params[:post_id]}_container", partial: 'posts/likes', locals: { post: @post }) }
end
Do the same in downvotes controller.
Now, if you reload the page and click on like or dislike, the changes should be real time.
No need to reload browser again. Cheers.