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

Why I Don't Use has_and_belongs_to_many in Rails

The magic of Rails makes it easy to create simple many-to-many relationships, but I almost never use it, and here's why.

Mar 31, 2015

Big Oops: Just a Few (Old) Notifications

I've learned a few things the hard way. How to properly use Active Record callbacks with Ruby on Rails is one of those things.

Jun 15, 2020

Preview Emails in Rails

Rails 4.1 introduced the ability to preview email messages from your mailers without sending an email. Learn how ...

Oct 23, 2014