#6 Hotwire Turbo: Increment likes count without any page refreshes
In this case we will replace a _likes
partial inside _inbox
partial, not the whole _inbox
partial. #
EVERYTHING IS PERSISTED IN THE DATABASE.
- console
rails g migration add_likes_to_inboxes like:integer
- the migration
add_column :inboxes, :likes, :integer, default: 0, null: false
- add the route
#config/routes.rb
Rails.application.routes.draw do
resources :inboxes do
member do
patch :like, to: 'inboxes#like'
end
end
end
- on event - replace the
_likes
partial - include
include ActionView::RecordIdentifier
- to usedom_id
- create a unique dom id for this specific partial
#app/controllers/inboxes_controller.rb
include ActionView::RecordIdentifier
def like
@inbox = Inbox.find(params[:id])
@inbox.increment!(:likes)
respond_to do |format|
format.turbo_stream do
render turbo_stream: turbo_stream.replace(
"#{dom_id(@inbox)}_likes",
partial: 'inboxes/likes',
locals: { inbox: @inbox }
)
end
end
end
- keep it in a partial with a unique dom
#app/views/inboxes/_likes.html.erb
<%= turbo_frame_tag "#{dom_id(inbox)}_likes" do %>
<%= inbox.likes %>
<% end %>
- render the partial in the view
- add the button
-
data: { turbo_frame: '_top' }
- might be optional
#app/views/inboxes/_inbox.html.erb
<div id="<%= dom_id inbox %>">
<h1><%= link_to inbox.name, inbox %></h1>
<%= render partial: 'inboxes/likes', locals: { inbox: inbox } %>
<%= button_to 'Like!',
like_inbox_path(inbox),
method: :patch, data: { turbo_frame: '_top' } %>
</div>
- you might want to move the
Like!
button into the partial.
Did you like this article? Did it save you some time?