views:

24

answers:

2

I have a ticket model which has a method inside called closes_in that calculates the time left from the DB field start_date:date to now. Currently my find query is:

    @tickets = Ticket.find(:all, 
                       :origin => @user.coords, 
                       :order => 'distance',

I can't just put in closes_in as I get an error. How do I make it so I can use closes_in to sort the query if it's a method and not an actual field in the DB?

+2  A: 

Use the sort_by method:

@tickets = Ticket.find(:all, :conditions => "foo").sort_by { |t| t.closes_in }
jpemberthy
How do you control in this example sorting ascending or descending?
Kevin
By default the `sort_by` method will return the collection ordered `ASC`, for `DESC` order you have to negate the `sort_by` elements, e.g: `Ticket.find(:all, :conditions => "foo").sort_by { |t| -t.closes_in }` (note the minus '-') returns the `@tickets` ordered `DESC`.
jpemberthy
A: 

If you are using MySQL:

@tickets = Ticket.all(:order => "DATEDIFF(CURDATE(), start_date)")

If you are using PostgreSQL:

@tickets = Ticket.all(:order => "AGE(start_date)")

This way you are using DB for sorting. Sorting using ruby should be restricted to a small data-set that is guaranteed to remain small.

KandadaBoggu
Thanks, does that work for Postgres?
Kevin
I have updated the answer with a solution for PostgreSQL
KandadaBoggu
Thanks! So in this case, I'll probably go with your solution though it will help to know the Ruby alternative that jpemberthy put above for other complicated methods that might not be easy to calculate in the DB.
Kevin
I use ruby sorting to smaller datasets(0-1000). When you need to perform pagination, grouping, sorting etc. its always better use built-in DB functionality before resorting to ruby.
KandadaBoggu