Skip to content
Menu
Railshero
  • Blog
  • About Me
  • Contact Me
  • Privacy Policy
Railshero
Adding Upvotes & Downvotes

Adding Upvotes & Downvotes in your rails app

Posted on July 21, 2021July 21, 2021 by Rails Hero

The Acts As Votable Gem

We can add likes/dislikes like youtube or upvotes/downvotes like reddit with a gem called ‘acts_as_votable’. This gem provides an easy process to add a voting functionality in your app. With this gem we can add upvote/downvote buttons and also count the number of upvotes/downvotes and display them easily.

Github Link: https://github.com/ryanto/acts_as_votable

How To Do It ?

Now, lets get started with adding a voting functionality in our app. To do it, follow the steps below

1. Add the acts as votable gem to your Gemfile and run bundler.

#File: Gemfile
gem 'acts_as_votable'
bundle install

2. Then run the migrations that comes with the gem.

rails g acts_as_votable:migration
rails db:migrate

This will generate a new table with the following columns.

voting tables

3. To make your model votable, add acts as votable to your model. For example: this is my book model. Please note that i used devise to add authentication to my app, and also i associated the user model with my book model.

#File: app/models/book.rb
class Book < ApplicationRecord
   acts_as_votable
   belongs_to :user
end

4. Now add a two new methods in your controller, to call for the upvotes and downvotes.

#File: app/controllers/books_controller.rb
class BooksController < ApplicationController

#...Other methods

   def upvote
      unless signed_in?
         redirect_to new_user_session_path
      else
         @book = Book.find(params[:id])
         @book.liked_by current_user
         redirect_to @book
      end
   end

   def downvote
      unless signed_in?
         redirect_to new_user_session_path
      else
         @book = Book.find(params[:id])
         @book.downvote_from current_user
         redirect_to @book
      end
   end

#...Other methods

end

5. Now, In your routes file, add the following methods to call for upvotes and downvotes from your views.

#File: config/routes.rb
Rails.application.routes.draw do
   resources :books do
      member do
         put "like", to: "books#upvote"
         put "dislike", to: "books#downvote"
      end
   end
end

6. Now in your views, you can add the number of upvotes/downvotes or likes/dislikes that the record currently has. And you can add buttons to peform those actions, you can customize the look of the buttons later, but here i kept it very simple, with just the bare bones.

#File: app/views/books/show.html.erb
#.....For Upvotes and Downvotes do this.....
<p>Upvotes <%= pluralize(number_to_human(@book.get_upvotes.size), 'Upvote') %></p>
<%= link_to "Upvote", like_book_path(@book), method: :put %>
<p>Downvotes <%= pluralize(number_to_human(@book.get_downvotes.size), 'Downvote') %></p>
<%= link_to "Downvote", dislike_book_path(@book), method: :put %>

#....Or For Likes and Dislikes do this....
<p>Upvotes <%= pluralize(number_to_human(@book.get_upvotes.size), 'Likes') %></p>
<%= link_to "Like", like_book_path(@book), method: :put %>

<p>Downvotes <%= pluralize(number_to_human(@book.get_downvotes.size), 'Dislike') %></p>
<%= link_to "Dislike", dislike_book_path(@book), method: :put %>

upvotes and downvotes

likes and dislikes

Final Thoughts

So, as i said earlier; this gem provides an easy way to add voting functionality to your app, there are also other features that comes with this gem, which i haven’t discussed(features like restricting a single vote to a single IP address). Please visit the gem’s page on github for a complete guide. And we can also build an entire voting functionality from scratch, in my upcoming posts, i’ll show you how to do that.

1 thought on “Adding Upvotes & Downvotes in your rails app”

  1. Pingback: Some Popular Gems For Your Rails Apps - Railshero

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Tags

active record active storage assets assign to many associations attachment attachments authentication authorization avatar bootstrap cdn config database deploy deployments devise DRY environment variables file uploads Gemfile gems has_many helpers heroku index indexing initializer javascript pagination parameters postgres production public routes.rb ruby gem ruby gems search sendgrid server smtp stylesheets variants views voting

Recent Posts

  • Understanding the DRY Principle in Rails
  • Building Multi-tenant Applications with Rails
  • Rails Basics: Templating Engines
  • Deploying With Capistrano
  • Automated Testing in Rails

Archives

  • July 2023
  • June 2023
  • October 2021
  • September 2021
  • August 2021
  • July 2021

Categories

  • Active Record
  • Activity Logging
  • Apps
  • Assets
  • Attachments
  • Audio
  • Authentication
  • Authorization
  • Deployments
  • Error Pages
  • File Uploads
  • General
  • Heroku
  • Heroku
  • Pagination
  • Rails Basics
  • RubyGems
  • Search Engine Optimization
  • Search/Indexing
  • Testing
  • User Interface
  • Video
  • Views & Templating
  • Voting
  • Web Security
©2025 Railshero | Theme: Wordly by SuperbThemes
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
Cookie SettingsAccept All
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT