Naturaily logo with transparent background

Ruby on Rails implementation of a ranking system using PostgreSQL

This article will show how easily you can add ranking functionality to your project. We will accomplish it, with the use of ntile() window function. I will be using Ruby on Rails for my application, with PostgreSQL database.

Illustration of an elephant with a red parachute floats gently in a pink sky with scattered clouds.

Hello, this article will show, how easily you can add ranking functionality to your project. We will accomplish it, with the use of ntile() window function. I will be using Ruby on Rails for my application, with PostgreSQL database.

We will need:

  • A model with integer attribute, by which we want to make the ranking (in my case, it’s visit_count). Here is an exemplary migration for Post model:

    tsx
  • Controller

tsx
  • Route for resource

tsx
  • View for our index action and partial for post

tsx
tsx

Here I won’t implement increment functionality for visit_count, because it's not the case of this article. We will just generate data by ourselves. For example by running this in Rails console:

tsx

Instead of adding method to Post model, I will just create Query Object called PostWithPopularityQuery, under app/query_objects/, to keep the model slim.

tsx

You can see constant POPULARITY_RANGES. This will be the number of 'levels' of popularity/ranking you want. Let's say it's 5. The ntile() window function will then apply value in range 1-5 to each record. In other words, it will divide it in n-tiles.

About the public static .call method itself: first, we call method .find_by_sql on model (in this case it's Post), and we just open quotes and write SQL.

What about the SQL? We specify which columns we want to retrieve, then we use the ntile(?) with OVER - this will be the criteria for ranking, visit_count exactly. We also have to use order by, it is required for using ntile. There is also something called popularity in here. I named it this way, but you can name it as you want. By this name, you will retrieve it’s ranking value, by calling it on instance of record (in my case, it’s post.popularity)

And now, how do we know what popularity value (between 1 and 5) does each Post have? Simply call .popularity on Post instance retrieved by Query Object method.

How our controller will look like now? Simple:

tsx

With templates specified earlier, we see something like this when we visit our Posts#index

A webpage displaying a list of posts with titles, descriptions, visit counts, and popularity scores. Each post is numbered and detailed.

Of course you might want something prettier than plain number. With a little effort, you can change it to something cool, for example stars. I decided to add gem font-awesome-rails for this article demo. With one small change in our partial file _post.html.erb, like this:

tsx

I've achieved result like this:

Web page displaying a list of posts with titles, descriptions, visit counts, and popularity ratings shown as stars.

Pros of this approach:

  • Clean and tidy

  • Fast-working (SQL window function is very efficient)

  • Quick to add

  • Little code

Cons: You tell me. Are there any?

Let’s Create a Great Website Together

We'll shape your web platform the way you win it!

More posts in this category

  • Core Web Vitals increase in traffic and sales. Graphic presenting man checking the website's metrics.

    September 30, 2025 • 9 min read

    How Much Will Improving Core Web Vitals Actually Increase My Traffic or Sales?

    Are you one of those business owners asking yourself, ‘Why isn’t my site ranking or converting as well as my competitors’? Even after investing in SEO and marketing, something can still feel missing. The problem often goes beyond keywords or ad spend and comes down to how fast and seamless the website feels to users. This is where Core Web Vitals optimization becomes essential.

    READ MORE
  • Illustration of people interacting with a large screen displaying analytics and a magnifying glass highlighting "#1," on a green background. It is a cover photo of a blogpost about Next.js.

    September 24, 2025 • 8 min read

    Next.js Websites for SaaS Scale-Ups: Why They’re the Growth Engine You Need

    SaaS companies in their scale-up phase face a bottleneck that rarely comes from a lack of product vision. The real slowdown lies in their digital infrastructure, most often their marketing and website layer.

    READ MORE
  • Illustration of a person wearing sunglasses and pointing out to a computer monitor. Above the monitor are icons representing visual, hearing, and speech impairments, symbolizing web accessibility and inclusive design.

    September 15, 2025 • 9 min read

    How Does Web Accessibility Impact SEO and Business Growth?

    Think of your website as a store where 1 in 4 customers can’t get through the door. That’s what happens when web accessibility is ignored. Small issues—like missing alt text or tiny buttons—block users, hurt conversions, and increase legal risk. Fixing them is simple, improves usability for everyone, and builds a stronger, more inclusive brand.

    READ MORE