Search code examples
ruby-on-railsrubyacts-as-votable

Sorting posts based on the most liked in Rails


I am trying to have two tabs, one for the most recent posts and the other is for the most liked posts. However, I am really stuck of how to get my post sorted by the most liked(voted). I did use acts_as_votable gem to get the voting system part into the website. I am new to Rails, let me know if what more details do you need to help out,thanks.


Solution

  • You should enable Caching. These columns will automatically be updated after each vote.

    Create new migration rails g migration add_cached_votes_to_posts and add below code:

    class AddCachedVotesToPosts < ActiveRecord::Migration
      def self.up
        add_column :posts, :cached_votes_total, :integer, :default => 0
        add_column :posts, :cached_votes_score, :integer, :default => 0
        add_column :posts, :cached_votes_up, :integer, :default => 0
        add_column :posts, :cached_votes_down, :integer, :default => 0
        add_column :posts, :cached_weighted_score, :integer, :default => 0
        add_column :posts, :cached_weighted_total, :integer, :default => 0
        add_column :posts, :cached_weighted_average, :float, :default => 0.0
        add_index  :posts, :cached_votes_total
        add_index  :posts, :cached_votes_score
        add_index  :posts, :cached_votes_up
        add_index  :posts, :cached_votes_down
        add_index  :posts, :cached_weighted_score
        add_index  :posts, :cached_weighted_total
        add_index  :posts, :cached_weighted_average
    
        # Uncomment this line to force caching of existing votes
        # Post.find_each(&:update_cached_votes)
      end
    
      def self.down
        remove_column :posts, :cached_votes_total
        remove_column :posts, :cached_votes_score
        remove_column :posts, :cached_votes_up
        remove_column :posts, :cached_votes_down
        remove_column :posts, :cached_weighted_score
        remove_column :posts, :cached_weighted_total
        remove_column :posts, :cached_weighted_average
      end
    end
    

    Run migration command rake db:migrate

    And use the cached column for ordering:

    Post.order(cached_votes_score: :desc)