ruby-on-railsacts-as-votable

Check if voted for Scope with a specific vote weight with Acts As Voteable


I’m using the acts as votable gem in my rails app, to give users the option to leave a 1-5 rating on a Resource under different scopes.


For example, Users can rate Location 1-5, Price 1-5 etc..

I currently have this code to check if a user has rated a specific scope. But how can I also check what vote_weight their vote had. ie: wether they rated 1,2,3,4 or 5?

Here:s my code for checking If they have voted on a specific scope:

    <% if (user_signed_in?) && (current_user.voted_for? @stadium, :vote_scope => ‘location) %>
    <p>Current user has rated the location for this Stadium</p>    
    <% else %>
    <p>Current user has NOT rated the location for this Stadium</p>    
    <% end %>

Here’s my code for saving the vote:

<%= link_to like_stadium_path(@stadium, :score => 1, :vote_scope => ‘location’), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 1
</button>
<% end %>
<%= link_to like_stadium_path(@stadium, :score => 2, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 2
</button>
<% end %>
    
<%= link_to like_stadium_path(@stadium, :score => 3, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 3
</button>
<% end %>
    
<%= link_to like_stadium_path(@stadium, :score => 4, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 4
</button>
<% end %>
    
<%= link_to like_stadium_path(@stadium, :score => 5, :vote_scope => 'location'), method: :put do %>
<button class="mt-4 w-full border-primary-500 border border-transparent rounded-md py-3 px-8 flex items-center justify-center text-base font-medium text-primary-500 hover:bg-primary-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
Vote 5
</button>
<% end %>

stadiums_controller.rb

def upvote 
@stadium.upvote_by current_user, :vote_scope => params[:vote_scope], :vote_weight => params[:score]
redirect_back(fallback_location: root_path)
end 

def downvote #deletes the vote from DB
@stadium.unliked_by current_user, :vote_scope => params[:vote_scope]
redirect_back(fallback_location: root_path)
end

routes.rb

  resources :stadiums do
    member do
      put "like", to: "stadiums#upvote"
      put "unvote", to: "stadiums#downvote"
    end
  end

Solution

  • you could create a method similar to the method voted_on? but return the weight instead of checking exists?

    class User < ApplicationRecord
      acts_as_voter
    
      def vote_weight_on(votable, vote_scope:)
        find_votes(
          votable_id: votable.id, 
          votable_type: votable.class.base_class.name, 
          vote_scope: vote_scope
        ).pluck(:vote_weight).first
      end
    end
    
    
    current_user.vote_weight_on(@stadium, vote_scope: "location")