2

I want to implement AJAX Upvote / Downvote on reviews of product (stackoverflow style).

I have a vote partial generated with each review:

_vote.html.erb

    <div id="vote_<%= review.id %>" class="vote">

      <%= link_to 'Vote Up', upvote_kata_review_path(@product, @review), :class => "upvote", :method => :post, :remote => true %>

      <span><%= review.plusminus %></span>  <!--show the current vote-->

      <%= link_to 'Vote Down', downvote_kata_review_path(@product, @review), :class => "downvote", :method => :post, :remote => true %>

    </div>

and an upvote.js.erb

$(document).ready(function(){
  $('#vote_id???').html("<%= escape_javascript render :partial => 'votes/vote' %>");
});

So when user clicks upvote, the partial will be re-rendered to show the new vote count.

The problem is, there are many reviews in a page. After the AJAX call, the JavaScript doesn't know which review's vote partial to re-render. (the $('#vote_id???') part)

Is there any way for Rails to pass the review id to the JavaScript?

Or any other alternative to implement this functionality.

Thanks in advance!

2
  • You don't need to wrap upvote.js.erb in a document ready, because the document should already be ready by the time the AJAX request is triggered. Commented Nov 8, 2012 at 22:27
  • Please show us the code of the upvote action. You should ideally have a @review variable defined in it, which could be used. Commented Nov 8, 2012 at 22:27

1 Answer 1

4

If you have a @review variable defined in the upvote action, like I suspect you might, then you can do this:

$('#vote_<%= @review.id %>').html("<%= escape_javascript render :partial => 'votes/vote' %>");
Sign up to request clarification or add additional context in comments.

5 Comments

That works! Just curious - is this a good practice to pass variable like this? and, is there a more elegant way to implement this voting functionality?
You're not really passing a variable here, you're just using what's made available to you through the request. The request routes to a URL which contains a review_id and inside your controller you're finding the matching review. Using it like you are doing is fine.
If the vote selector is defined within the partial, it is helpful to use jQuery's replaceWith rather than html. While both would most likely work for the user, using html will leave behind extra elements.
So anything available in the controller is available in a .js.erb file.
Any instance variable defined in a controller's action is available in any template (be it a view or a partial) rendered by that action.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.