Order Rails Query by Virtual Attribute

Rails' scopes don't work well with virtual attributes since they resolve to a SQL query. Instead you can throw them in an array and then sort by a virtual attribute.

Have you tried and failed to order a rails query by a virtual attribute, being told the column isn't in the database (when, in fact, you already knew that)?

Let's say you have a User model that has a name attribute that you've split up on the fly. Something like this.

class User < ActiveRecord::Base

def first_name
return email if name.nil?
name.split(' ').first

def last_name
return email if name.nil?
name.split(' ').last


You've probably tried and failed with a scope like this.

scope :by_name, -> { order('last_name asc') }

What you have to do is first load the objects you want into memory and then use Ruby's sort_by array method to sort the collection of objects. So, something like this would work.

scope :by_name, -> { all.to_a.sort_by(&:last_name) }

Let's Connect

Keep Reading

Use Slack For Rails Error Notification

Post a message to one of your Slack channels when your Rails app encounters a 500 error.

Dec 22, 2015

How we apply the Rails Doctrine to the Jamstack

Just like omakase sushi is solely the chef's choice, the biggest benefit to any framework is when it makes (good) decisions for you.

Oct 01, 2020

3 Reasons Why Turbolinks Is Not Worth The Effort

Turbolinks is a great idea in theory, but it comes with enough problems to offset its benefits.

Mar 15, 2016