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

Instantiate a Class from a String in Rails

Rails classes need to be called dynamically sometimes. Learn how to do it using the constantize inflector.

Nov 20, 2014

Transition Between Database Adapters in Rails

Transitioning from one database to another, or even to a whole new database with a new adapter, can be tough. Here's an easy way to transition content.

May 25, 2015

Bi-Directional has_and_belongs_to_many on a Single Model in Rails

Bi-directional HABTM relationships are easy in Rails, but when you need to do it on a single model, that's when it gets tricky. Here's one approach.

May 04, 2015