Now Available for Rails 8+

Voting infrastructure
for modern Rails

VoteFu brings first-class Turbo Streams, ViewComponents, and view helpers to your voting system. Built-in ranking algorithms. Zero external dependencies.

# Gemfile
gem 'vote_fu', '~> 2.0'

# Then run:
rails generate vote_fu:install
rails db:migrate

Built for how Rails works today

Not a port from 2010. Designed from the ground up for Rails 8, Hotwire, and modern patterns.

Turbo-Native

Every vote action returns Turbo Stream responses by default. Mount the engine and get seamless updates with zero JavaScript.

🧩

ViewComponents

Drop-in components for vote widgets, star ratings, and emoji reaction bars. Fully customizable with CSS variables.

Flexible Voting

Up/down votes, star ratings (1-5), weighted votes, or emoji reactions. One gem handles all voting patterns.

📊

Built-in Algorithms

Wilson Score, Reddit Hot, and Hacker News ranking built-in. No external gems required.

🔍

Scoped Voting

Same user can cast multiple independent votes in different contexts. Rate helpfulness AND quality on the same item.

🏆

Karma System

Calculate user reputation from votes on their content. Built-in support for author karma across multiple models.

How VoteFu compares

The voting gem landscape hasn't kept up with Rails. We're changing that.

Feature ThumbsUp Votable VoteFu 2.0
Rails 8 Support No No Yes
Vote Values Boolean Integer Integer
Turbo Streams No No Native
ViewComponents No No Included
View Helpers No No Included
Counter Cache No Running total Both
Scoped Voting No Yes Yes
Karma System No No Built-in
Wilson Score External gem No Built-in
Hot Ranking No No Built-in

Simple, expressive API

Everything you need, nothing you don't.

Setup your models
class Post < ApplicationRecord
  acts_as_voteable
end

class User < ApplicationRecord
  acts_as_voter
  has_karma :posts, as: :author
end
Cast votes
# Simple voting
user.upvote(post)
user.downvote(post)
user.toggle_vote(post)
user.unvote(post)

# Star ratings
user.vote_on(post, value: 5)

# Scoped voting
user.vote_on(review, value: 5, scope: :quality)
user.vote_on(review, value: 1, scope: :helpfulness)
Query votes
# On voteables
post.votes_for            # Upvotes
post.votes_against        # Downvotes
post.plusminus            # Net score
post.wilson_score         # Ranking (0.0-1.0)
post.voted_by?(user)

# On voters
user.voted_on?(post)
user.vote_value_for(post)
user.karma
Rank items
# Order by votes
Post.by_votes
Post.by_wilson_score
Post.trending              # Last 24h
Post.with_positive_score

# Scoped queries
review.plusminus(scope: :quality)
review.plusminus(scope: :helpfulness)
View helpers
<%# Reddit-style widget %>
<%= vote_widget @post %>

<%# Simple like button %>
<%= like_button @photo %>

<%# Scoped voting %>
<%= vote_widget @review, scope: :quality %>
<%= vote_widget @review, scope: :helpfulness %>
ViewComponents
<%# Star rating %>
<%= render VoteFu::StarRatingComponent.new(
  voteable: @product,
  voter: current_user,
  show_average: true,
  show_count: true
) %>

<%# Emoji reactions (Slack/GitHub style) %>
<%= render VoteFu::ReactionBarComponent.new(
  voteable: @comment,
  voter: current_user,
  reactions: [
    { emoji: "👍", scope: "like" },
    { emoji: "❤️", scope: "love" },
    { emoji: "🎉", scope: "celebrate" }
  ]
) %>

Easy to customize

Configure behavior and style with simple APIs.

Configuration
# config/initializers/vote_fu.rb
VoteFu.configure do |config|
  config.allow_recast = true
  config.allow_self_vote = false
  config.counter_cache = true
  config.turbo_broadcasts = true
  config.default_ranking = :wilson_score
  config.hot_ranking_gravity = 1.8
end
Mount the engine
# config/routes.rb
Rails.application.routes.draw do
  mount VoteFu::Engine => "/vote_fu"
end

# Turbo Stream endpoints:
# POST   /vote_fu/votes
# POST   /vote_fu/votes/toggle
# DELETE /vote_fu/votes/:id
CSS Variables
/* Import default styles */
@import "vote_fu/votes";

/* Customize colors */
:root {
  --vote-fu-upvote-color: #ff6314;
  --vote-fu-downvote-color: #7193ff;
  --vote-fu-like-color: #e0245e;
}
Counter caches
# Migration
add_column :posts, :votes_count, :integer, default: 0
add_column :posts, :votes_total, :integer, default: 0
add_column :posts, :upvotes_count, :integer, default: 0
add_column :posts, :downvotes_count, :integer, default: 0

# Counters update automatically

Ready to add voting to your app?

VoteFu 2.0 is available now. Install it and start building.