Using Rails 3, JRuby.
I wanted to incorporate a "vote up" and "vote down" rating for my Rails social application, that allows users to essentially like and dislike posts. This worked great, however refreshed the whole page whenever a post was voted on. To solve this, I wanted to implement a partial refresh that would only update that particular post score, within the post feed.
I followed my usual pattern to implementing AJAX partial refreshing, however, the outcome isn't quite what I had in mind. Instead of refreshing the post I like/dislike, it refreshes the most recent post with the new score of the post I just liked/disliked.
I've identified this as a partial refreshing problem, because when I refresh the whole page manually, each post has its correct like/dislike score (including the one I intended to alter). I believe the problem is to do with the way my page renders posts to the page using a "do block". My problem is, I cannot figure out how to get the desired behaviour of correctly refreshing the micropost I voted on. Here is some of my code:
_micropost.html.erb (partial)
<% microposts.each do |mp| %>
<div class="profile_block gradient ">
<!-- Header -->
<header class="top-bar">
<small class="badge sharp">Post</small>
<!-- post/ article options -->
<% if mp.user_id == current_user.id %>
<%= link_to '<span class="glyphicon glyphicon glyphicon-cog"></span>'.html_safe, '#', class: "comment_link pull-right"%>
<% end %>
<%= link_to '<span class="glyphicon glyphicon glyphicon-heart"></span>'.html_safe, increment_micropost_path(mp.id), class: "comment_link pull-right", :remote => true%>
<%= link_to '<span class="glyphicon glyphicon glyphicon-thumbs-down"></span>'.html_safe, decrement_micropost_path(mp.id), class: "comment_link pull-right", :remote => true %>
<div id="global" class="pull-right badge"><%= render :partial => 'microposts/rating', :locals => {:micro => mp} %></div>
</header>
(....)
<% end %>
</div>
_home.html.erb
(....)
<div id="gf" class="left_col">
<%= render :partial => 'microposts/micropost', :locals => {:microposts => @microposts }, :remote => true %>
</div>
(....)
my _rating.html.erb partial (the bit that displays the information)
<%= micro.rating.to_i %>
controller (i'll just show the increment method, they're both near identical
#increments micropost rating by 1
def increment
@micropost = Micropost.find(params[:id])
@increment = lambda { |micropost| micropost.update_attribute(:rating, micropost.rating.to_i + 1) }
@increment.call @micropost
respond_to do |format|
format.html {redirect_to root_url}
format.js
end
end
and the corresponding increment.js.html
$('#global').html("<%= escape_javascript render :partial => 'microposts/rating', :locals => {:micro => @micropost} %>");
I mentioned above that the actual incrementing/ decrementing feature of the micropost works fine- it's just re-rendering this information using AJAX that's not behaving as intended. Any ideas, please share.