Rails – How to sort a model on a virtual attribute

[Reading time: 2mn]

Ruby 1.9.2-p180
Rails 3.0.4

The Problem
So you have a Product model with a couple of virtual attributes like user rating which depends on some clever calculation. It is declared as an instance def in the model, a.k.a: a virtual attribute (ps: remember that class defs – e.g.: def self.do_something – apply to the records as a whole, whereas instance defs – e.g.: def do_something – apply to the current record). But I digress.
Actually you want to sort the products on this user rating but you know that scopes only work at the database level.

The Solution
Well, arrays in Ruby have a sort_by method. So here’s what you could do:

def self.sorted_by_rating_down
  Product.all.sort_by {|p| - p.user_rating}
def self.sorted_by_rating_up
  Product.all.sort_by {|p| p.user_rating}

To be continued…
Indeed, the astute reader may have just had an idea: why not try to unify all these sort functions? Stay tuned, this will be the subject of our next post.


Leave a Reply

Your email address will not be published. Required fields are marked *