Adding a "Like/Unlike" Button to a Post in Rails

Adding a Like/Unlike button to a post in Rails

You should define association in user model

if it's ror 2.* add method in User model. it should look like this:

has_many :likes
def already_likes?(post)
self.likes.find(:all, :conditions => ['post_id = ?', post.id]).size > 0
end

Assuming Like has fields user_id and post_id
and of course in view

if current_user.already_likes?(@post)
#add unlike button
end

Adding AJAX to Rails 4 Like/Unlike Button with Counter

You are redirecting the request before reaching the respond_to block. Anything that comes after redirect_to will not run. You are also missing an end statement to close your respond_to block. I'm assuming you only want to redirect the user on an HTML request. If so change the ending of your create and destroy methods to this:

respond_to do |format|
format.html { redirect_to project_path(project), :notice => "Some message" }
format.js { render 'your_javascript_file' }
end

Now you'll need some Javascript files to actually change the web page. Whether you'll need one or two Javascript files is up to you and how you want each link to behave after it's clicked.

Adding ajax to like button in Rails app

Here I am using a single method as you never want the likes count to go below zero.

Whenever the user likes a post, the count increments by 1 and the color of the thumbs-up icon changes(just to show a visual change).

When the user clicks on an already liked post the count of likes should be reduced by one so we should use the unliked_by method provided by the gem.

For implementing this we can use an upvote.js.erb file (remember the file name should be same as your controller method name it makes the process easier).

Then in the .js.erb file we can mix ruby with js and have the desired result as shown in the upvote.js.erb file.

I add an extra class called liked which changes the color of the button.

Please Note: I am assuming that you have a single post on a page. If you have multiple posts on a page then you should add ID's to the posts container and similarly change the js code in the upvote.js.erb file.

posts_controller.rb

  def upvote
if !current_user.liked? @post
@post.liked_by current_user
elsif current_user.liked? @post
# as the above method can also result nil if he is yet to vote
@post.unliked_by current_user
end
end

views/posts/upvote.js.erb

<% if current_user.liked? @post %>
document.getElementsByClassName('like-btn')[0].className = "like-btn liked";
<% else %>
document.getElementsByClassName('like-btn')[0].className = "like-btn";
<% end %>
document.getElementsByClassName('likes-count')[0].innerHTML="<%= @post.get_upvotes.size %>";

view.html.erb

<!-- Adding a class liked -->
<style>
.liked {
color: blue;
}
</style>
<%= link_to like_post_path(@post), class:"like-btn", method: :put, remote: true do %>
<button class="btn btn-warning">
<span><p><i class="fa fa-thumbs-up fa-lg" aria-hidden="true"></i></p></span>
</button>
<% end %>
<span class="likes-count"> <%= @post.get_upvotes.size %> </span>

Simple like/unlike button with rails 3, jquery, and ajax

My answer to your question is long, so I wrote up an example application. Here's a snippet:

There are many ways to skin this cat, but I like to render a partial and a single ujs template.

_like_button.html.erb:

<% if like = current_user.likes.find_by_product_id(@product.id) %>
<%= form_for like, :html => { :method => :delete },
:remote => true do |f| %>
<%= f.submit "Unlike" %>
<% end %>
<% else %>
<%= form_for current_user.likes.build(:product_id => @product.id), :remote => true do |f| %>
<%= f.hidden_field :product_id %>
<%= f.hidden_field :user_id %>
<%= f.submit "Like" %>
<% end %>
<% end %>

toggle.js.erb, where "#like" is the div enclosing the form:

$("#like").html("<%= escape_javascript render('like_button') %>");

Building a form for a like button in a polymorphic relationship in Rails

This should work:

= form_for([@post, @post.likes.find_by(user_id: current_user.id)], html: {method: :delete}) do |f|

url: post_like_path(@post) in your code expects a second argument (the like object). That's what throws the error.
But you don't need it actualy if you put the nested resources as an array in the first argument of the form_for helper.

If the record passed to form_for is a resource, i.e. it corresponds to
a set of RESTful routes, e.g. defined using the resources method in
config/routes.rb. In this case Rails will simply infer the appropriate
URL from the record itself.
(source: http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for)

You can pass an array of resources if your resource is nested within another resource.

Now... You probably want to re-use this code for your other polymorphic models as well. You can do this by passing @post, or @comment to your partial like this:

= render :partial => 'like_button', locals: {likable: @post}

and refactor your partial like this:

= form_for([likable, likable.likes.find_by(user_id: current_user.id)], html: { method: :delete}) do |form|

Rails: Ajax for Like Button and Updating Like Count

But why are you doing this in your view?

<% @post = user.posts.first %>

It will update only your first post always. I can't understand.

Try with this:

_liked_users.html.erb

<%= @updated_post = Post.where(id: @post.id) %>    
<%= "#{@updated_post.likes.length} like this" %>

or

<%= @post.reload %>    
<%= "#{@post.likes.length} like this" %>

Edit (Try to build your like this):

def create
@post = Post.where(id: params[:post_to_be_liked])
@like = @post.likes.build(:post_id => @post.id)
if @like.save
respond_to do |format|
format.html {redirect_to :back, notice: "Liked!"}
format.js
end
end
end

ajax in ruby on rails for a like/unlike button

= link_to "Like", like_comment_path(comment), method: :post, remote: true

Then in your likes_controller create action, respond_to format.js

def create
respond_to do |format|
format.html { .. your liking code .. }
format.js {.. your liking code .. }
end
end

This will then invoke the create.js.erb in your view folder, and you can dynamically update your html from there



Related Topics



Leave a reply



Submit