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
Retrieving Image Height with Carrierwave
Display Base64 Encoded Image in Rails
Ruby on Rails - Paperclip and Dynamic Parameters
Solving the Travelling Salesman Problem in Ruby (50+ Locations)
Split Array Up into N-Groups of M Size
Does Concurrency Happen Even When Only One Thread Is in a Thread Pool
Ruby on Rails - Is Params a Method or a Hash
Ending a Rails 2 Url with an Ip Address Causes Routing Error
Consuming Non-Rest APIs in Rails with Activeresource
Add a Callback Function to a Ruby Array to Do Something When an Element Is Added
Gem Install Mongrel Fails with Ruby 1.9.1
Postgres Range Fields + Rails Forms
How to Run a Simple Ruby Script in Any Web Server (Apache or Mongrel or Any Thing Else)
Ruby on Rails: Conditionally Display a Partial
Appending Headers to Rspec Controller Tests
How to Return Correct Http Error Codes from Ruby on Rails Application