8

I have a product, user, and like model. A user can like a product. I am trying to implement a simple like button which, upon a click, allows a user to like a product. Then the like button transforms into an unlike button, allowing the user to unlike a product. Pretty straightforward.

I have implemented the model/controller logic for the above. I am not very good with javascript/ajax and was wondering what the best way would be to implement the above functionality. I want the like/unlike actions to be handled via ajax. I am using rails 3 and jquery ujs for my app.

Thanks.

deruse
  • 2,851
  • 7
  • 40
  • 60

2 Answers2

36

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') %>");
dwhalen
  • 1,927
  • 12
  • 11
  • 1
    Man, its so awesome that you did this. Your sample app really helped me understand how this works. Thx a ton! – p01nd3xt3r Jul 23 '11 at 01:36
  • 1
    @dwhalen, I cannot find the linked sample application anymore. I am trying to do the same thing in my app, and I have almost identical code in my application. The first time around everything works fine, the Like button shows up, and on clicking it, it toggles to unlike. However, when I try to click the unlike button, nothing happens. Any suggestions? – Anand Apr 26 '12 at 10:52
  • How can I add something to the database so that I can actually view this sample in action? – finiteloop Jul 05 '12 at 17:39
  • Follow the readme: https://github.com/invisiblefunnel/soquestion6482354#getting-started. `rake db:seed`. – dwhalen Jul 05 '12 at 18:34
  • @dwhalen, thanks a lot for the example! I understand better now :) I only have one problem : when I click "Unlike", I get an error in the log `ActiveRecord::RecordNotFound (Couldn't find Like with id=11): app/controllers/likes_controller.rb:9:in `destroy'`. The "Unlike" does not get updated to "Like" until I click again... Do you know why? – Justin D. Jul 10 '12 at 14:21
  • Nice sample app, i just wish it was complete so we can see your sample app in action. – Serge Pedroza Feb 08 '13 at 02:25
  • FYI you can find the source for the example app at the following forks: https://github.com/shihabullal/soquestion6482354, https://github.com/shihabullal/soquestion6482354, https://github.com/sergeylukin/soquestion6482354, https://github.com/haon/soquestion6482354 – dwhalen May 06 '13 at 20:12
1

Basically, to make your links work via AJAX, you just need to provide link_to with :remote => true argument. But I guess you want to make some sort of feedback to the user. Take a look at this screencast.

bassneck
  • 4,053
  • 4
  • 24
  • 32