The app allows users to vote on embedded videos. When users click up and down arrows, the whole page refreshes to update points
. I have been attempting to implement AJAX voting for months now. I would like the most straightforward solution you can offer, even if it isn't the most efficient. Any ideas?
My up
and down
actions from app/controllers/links_controller
....
def up
@link = Link.find(params[:id])
@link.update_attribute :points, @link.points + 1
redirect_to :back
end
def down
@link = Link.find(params[:id])
@link.update_attribute :points, @link.points - 1
redirect_to :back
end
....
A minimalist version of links_list
, a partial from app/views/links/_links_list
, which I render in other views using various sorting methods
<% @links.each do |link| %>
<div class="row">
<div class="span2">
<%= link_to (image_tag ("up.png")), up_link_url(link), :method => :put %>
<%= link.points %>
<%= link_to (image_tag ("down.png")), down_link_url(link), :method => :put %>
</div>
<div class="span8">
<%= link_to strip_tags(link.title), link %>
</div>
</div>
<% end %>
Thanks in advance for any feedback or suggestions!
Ajax is pretty easy to use in Rails 3.1. This post assumes you're using jQuery as your JavaScript driver; if you aren't, you'll need to install the jquery-rails gem, but even for an app in production adding a small gem shouldn't be a really big deal.
Your controller will end up looking like this:
....
def up
@link = Link.find(params[:id])
@link.update_attribute :points, @link.points + 1
respond_to do |format|
format.html {redirect_to :back}
format.js
end
end
def down
@link = Link.find(params[:id])
@link.update_attribute :points, @link.points - 1
respond_to do |format|
format.html {redirect_to :back}
format.js
end
end
....
The view change will be pretty small:
<% @links.each do |link| %>
<div class="row">
<div class="span2">
<%= link_to (image_tag ("up.png")), up_link_url(link), :method => :put, :remote => true %>
<%= link.points %>
<%= link_to (image_tag ("down.png")), down_link_url(link), :method => :put, :remote => true %>
</div>
<div class="span8">
<%= link_to strip_tags(link.title), link %>
</div>
</div>
And you'll need new files, up.js.erb and down.js.erb, in your app/views/links/ folder, which contains the JavaScript command to update your page:
$(".span2").html("This post has <%= @link.points %> points.")
If you decide to go with Prototype or something the code will look more or less the same; the only change will be the JavaScript you place in up.js.erb and down.js.erb, which should be Prototype-y instead of jQuery-y.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With