Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Act As Votable Ajax Fail

I'm new to ruby and I just played around with a demo app. I've included the gem acts_as_votable, and it works quite well except for one fact that I thing its missing... ajax. Refreshing all the time the page its a bit tedious so I've "tryed" to implement ajax, but no luck :(. After maybe two hours of resource I think I can't do nothing more. I need help on implementing ajax on down and up votes. Thanks a lot.

Here is my code:

entries_controller.rb

  def upvote
    @entry = Entry.find(params[:id])
    unless current_user.voted_for? @entry
      @entry.vote_total = @entry.vote_total + 1
      @entry.save
      @entry.upvote_by current_user
    else
      flash[:danger] = 'Sorry!! You had allready voted this entry!'
    end
    redirect_to :back
  end

  def downvote
    @entry = Entry.find(params[:id])
    unless current_user.voted_for? @entry
      @entry.vote_total = @entry.vote_total + 1
      @entry.save
      @entry.downvote_by current_user
    else
      flash[:danger] = 'Sorry!! You had allready voted this entry!'
    end
    redirect_to :back
  end

_entry.html.erb (in entries folder)

<aside class="vote-count bind-<%= entry.id %>">
  <%= link_to like_entry_path(entry), :remote => true, method: :put, class: 'vpos' do %>
  <i class="fa fa-thumbs-up"></i>
    <%= entry.get_upvotes.size %>
  <% end %>
  <%= link_to dislike_entry_path(entry), :remote => true, method: :put, class: 'npos' do %>
    <i class="fa fa-thumbs-down"></i>
  <%= entry.get_downvotes.size %>
  <% end %>
</aside>

upvote.js.erb (in entries folder)

$(".bind-<%=entry.id%>").html('<%=escape_javascript entry.get_upvotes.size %>');

routes.rb

resources :entries,  only: [:index, :show, :new, :create, :destroy] do
  member do
    put 'like', to: 'entries#upvote'
    put 'dislike', to: 'entries#downvote'
  end
end

I'm a bit new to rails so anykind of help. would be much appreciated!! Thanks

like image 580
Sergio Mironescu Iancu Avatar asked Dec 04 '14 20:12

Sergio Mironescu Iancu


1 Answers

Finnaly I've managed to make it working (acts as votable gem, the votes are now ajax). I'm going to share it incase someone has the same issue as me.

routes.rb :

put 'like', to: 'entries#upvote'
put 'dislike', to: 'entries#downvote'

entries_controller.rb (in my case):

def upvote
  @entry = Entry.find(params[:id])
  respond_to do |format|
  unless current_user.voted_for? @entry
    format.html { redirect_to :back }
    format.json { head :no_content }
    format.js { render :layout => false }
    @entry.vote_total = @entry.vote_total + 1
    @entry.save
    @entry.upvote_by current_user
  else
    flash[:danger] = 'You allready voted this entry'
    format.html { redirect_to :back }
    format.json { head :no_content }
    format.js
  end
 end
end

def downvote
  @entry = Entry.find(params[:id])
  respond_to do |format|
  unless current_user.voted_for? @entry
    format.html { redirect_to :back }
    format.json { head :no_content }
    format.js { render :layout => false }
    @entry.vote_total = @entry.vote_total + 1
    @entry.save
    @entry.downvote_by current_user
  else
    flash[:danger] = 'You allready voted this entry'
    format.html { redirect_to :back }
    format.json { head :no_content }
    format.js
  end
 end
end

_entry.html.erb (partial):

<aside class="vote-count bind-<%= entry.id %>">
 <%= link_to like_entry_path(entry), :remote => true, method: :put, class: 'vpos' do %>
  <i class="fa fa-thumbs-up"></i>
  <span class="vcount-<%= entry.id %>"><%= entry.get_upvotes.size %></span>
 <% end %>
 <%= link_to dislike_entry_path(entry), :remote => true, method: :put, class: 'npos' do %>
  <i class="fa fa-thumbs-down"></i>
  <span class="ncount-<%= entry.id %>"><%= entry.get_downvotes.size %></span>
 <% end %>
</aside>

upvote.js.erb:

$('.vpos').bind('ajax:success', function() {
 $('.vcount-<%= @entry.id %>').html('<%=escape_javascript @entry.get_upvotes.size.to_s %>');
});

downvote.js.erb:

$('.npos').bind('ajax:success', function() {
 $('.ncount-<%= @entry.id %>').html('<%=escape_javascript @entry.get_downvotes.size.to_s %>');
});

That's all. Hope that I can help someone that needs a hand with this. Cheers.

like image 177
Sergio Mironescu Iancu Avatar answered Sep 17 '22 08:09

Sergio Mironescu Iancu