Jbur43
Jbur43

Reputation: 1312

acts_as_votable ordering based on upvotes in controller

I am using the acts_as_votable gem to order my links based on how many up-votes they get from users.

I used a .each iterator in my view originally to handle the ordering and it worked fine:

@links.order(cached_votes_up: :desc).each do |link|

But now I am trying to include the ordering functionality in my controller and it is not working. I tried a few different ways:

class LinksController < ApplicationController
  before_filter :authenticate_user!, except: [:index, :show]

  def index
    @links = Link.order(cached_votes_up: :desc)
    @links = Link.paginate(page: params[:page], per_page: 5)

    respond_to do |format| 
      format.js
      format.html
    end
  end
end

    class LinksController < ApplicationController
      before_filter :authenticate_user!, except: [:index, :show]

      def index
        @links = Link.order(cached_votes_up: :desc).paginate(page: params[:page], per_page: 5)

        respond_to do |format| 
          format.js
          format.html
        end
      end
end


class LinksController < ApplicationController
  before_filter :authenticate_user!, except: [:index, :show]

  def index
    @links = Link.order(cached_votes_up: :desc)
    @links.paginate(page: params[:page], per_page: 5)

    respond_to do |format| 
      format.js
      format.html
    end
  end
end

My _link partial:

<div class="link row clearfix">
    <h2>
      <%= image_tag link.avatar.thumb %>
    </h2>
    <h2>
      <%= link_to link.title, link %><br>
    </h2>
    <p>
      <%= link_to link.url, link %><br>
    </p>


<!-- acts_as_votable for like_link -->
    <div class="btn-group">
        <%= link_to like_link_path(link), method: :put, class: "btn btn-default btn-sm" do %>
          <span class="glyphicon glyphicon-chevron-up"></span>
          Upvote
          <%= link.get_upvotes.size %>
        <% end %>
        <%= link_to dislike_link_path(link), method: :put, class: "btn btn-default btn-sm" do %>
          <span class="glyphicon glyphicon-chevron-down">
          Downvote
          <%= link.get_downvotes.size %>
        <% end %>
    </div>
</div>

index.html.erb:

<div id="link"><%= render @links %></div>

<%= will_paginate @links %>

Does anyone see what the problem could be or what I may be doing wrong?

This is the output when I run Link.order(cached_votes_up: :desc). Even though I downvoted this post, it is still returning the object as containing an upvote?

irb(main):001:0> @link = Link.order(cached_votes_up: :desc).first
  Link Load (2.0ms)  SELECT  "links".* FROM "links"  ORDER BY "links"."cached_votes_up" DESC LIMIT 1
=> #<Link id: 16, title: "John F Kennedy", url: "Change is the law of life. And those who look only...", created_at: "2015-12-26 23:56:26", updated_at: "2015-12-26 23:56:31", user_id: nil, cached_votes_total: 1, cached_votes_score: 1, cached_votes_up: 1, cached_votes_down: 0, avatar: "jfk.jpeg">

This is my link model containing the acts_as_votable object:

class Link < ActiveRecord::Base
    self.per_page = 5
    belongs_to :user
    validates :user, presence: true
    acts_as_votable
    attr_accessor :avatar
    mount_uploader :avatar, AvatarUploader
end

This is my routes file:

Rails.application.routes.draw do
  devise_for :users
  resources :users
  resources :links do
    member do
      put "like", to: "links#upvote"
      put "dislike", to: "links#downvote"
    end
  end
  root to: "links#index"

These are my downvote and upvote actions:

  def upvote
    @link = Link.find(params[:id])
    @link.upvote_by current_user
    redirect_to :back
  end

  def downvote
    @link = Link.find(params[:id])
    @link.downvote_from current_user
    redirect_to :back
  end

Upvotes: 1

Views: 292

Answers (2)

MilesStanfield
MilesStanfield

Reputation: 4639

Since you say in your comments your actually having problems registering a downvote, this may help you

According to acts_as_votable gem docs

By default all votes are positive

So

@post.vote_by :voter => @user3

Is actually a positive vote. To down vote you need to do something like this ...

@post.vote_by :voter => @user4, :vote => 'bad'

Or

@post.downvote_from @user2

Upvotes: 0

Yang
Yang

Reputation: 1923

Please try this:

class LinksController < ApplicationController
  before_filter :authenticate_user!, except: [:index, :show]
  def index 
    ordered_links = Link.order(cached_votes_up: :desc)
    @links = ordered_links.paginate(page: params[:page], per_page: 5)

    respond_to do |format| 
      format.js
      format.html
    end
  end
end

Upvotes: 1

Related Questions