Home

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
end

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

end

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

Rails has_many :through Polymorphic Association

How to maintain HMT behavior on a polymorphic association.

Oct 13, 2014

Run Multiple Rails Servers at the Same Time

It's annoying to shut down and start up your Rails server when jumping between projects. Learn how to run multiple servers at the same time.

Oct 24, 2014

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