"How to implement a like function in Rails" introduced how to implement a like function, but this time Will introduce how to implement the like function in Ajax (asynchronous communication). The completed system looks like the following.
- This article has implemented the like function.
Add remote: true </ b> to the two link_to (method:: delete and method: post). By describing remote: true, processing in Ajax can be executed.
html:index.html.erb
<div class="container">
<h1>List of articles</h1>
<table class="table">
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td>
<% if post.liked_by?(current_user) %>
<% like = Like.find_by(user_id: current_user.id, post_id: post.id) %>
<%= link_to like_path(like), method: :delete, remote: true do %>
<span class="glyphicon glyphicon-heart" aria-hidden="true" style="color: red;">
<span><%= post.likes.count %></span>
<% end %>
<% else %>
<%= link_to post_likes_path(post), method: :post, remote: true do %>
<span class="glyphicon glyphicon-heart" aria-hidden="true" style="color: gray;">
<span><%= post.likes.count %></span>
<% end %>
<% end %>
</td>
</tr>
<% end %>
</table>
</div>
Create the following file in the same directory as index.html.erb, copy and paste the like function part.
html:_like.html.erb
<% if post.liked_by?(current_user) %>
<% like = Like.find_by(user_id: current_user.id, post_id: post.id) %>
<%= link_to like_path(like), method: :delete, remote: true do %>
<span class="glyphicon glyphicon-heart" aria-hidden="true" style="color: red;">
<span><%= post.likes.count %></span>
<% end %>
<% else %>
<%= link_to post_likes_path(post), method: :post, remote: true do %>
<span class="glyphicon glyphicon-heart" aria-hidden="true" style="color: gray;">
<span><%= post.likes.count %></span>
<% end %>
<% end %>
In order to call the partial template (_like.html.erb), write render </ b> where there was a like function part. Also, describe the id so that you can identify the part where Ajax is processed.
html:index.html.erb
<div class="container">
<h1>List of articles</h1>
<table class="table">
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td id="like-<%= post.id %>"> <!--Make it identifiable by id-->
<%= render "like", post: post %> <!--Call partial template with render-->
</td>
</tr>
<% end %>
</table>
</div>
I used to do redirect_back at the end of each action, but when I do redirect_back, it reloads and Ajax doesn't work. Therefore, remove redirect_back.
likes_controller.rb
def create
like = Like.new(user_id: current_user.id, post_id: params[:post_id])
@post = like.post
like.save
end
def destroy
like = Like.find(params[:id])
@post = like.post
like.destroy
end
Since we are sending a js format request by remote: true, we will finally look for the js file with the action name (create or destroy) to execute. Therefore, create a likes folder under app / views /, and create.js.erb and destory.js.erb in that folder.
js:create.js.erb
$("#like-<%= @post.id %>").html("<%= j(render 'posts/like', post: @post) %>");
js:destory.js.erb
$("#like-<%= @post.id %>").html("<%= j(render 'posts/like', post: @post) %>");
Identifies by id and partially rewrites html. That's all there is to it.
Recommended Posts