order
order(*args)Allows to specify an order attribute:
User.order('name') => SELECT "users".* FROM "users" ORDER BY name User.order('name DESC') => SELECT "users".* FROM "users" ORDER BY name DESC User.order('name DESC, email') => SELECT "users".* FROM "users" ORDER BY name DESC, email User.order(:name) => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC User.order(email: :desc) => SELECT "users".* FROM "users" ORDER BY "users"."email" DESC User.order(:name, email: :desc) => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
6Notes
Reorder
If you want to override previously set order (even through default_scope), use reorder() instead.
E.g.
User.order('id ASC').reorder('name DESC')
would ignore ordering by id completely
Ordering on associations
For ordering on the attribute of an associated model you have to include it:
Package.includes(:package_size).order("package_sizes.sort_order")
using hash as order
order can be specified as a hash, e.g.:
order(id: :desc)
This will prevent "ambiguous column" errors when the order is used with joins or includes.
Ordering on associations using merge
For ordering on the attribute of an associated model you can add joins to query and merge order scope: Product.joins(:category).merge(Category.order(priority: :desc))
reorder
adding to stevo's comment that reorder is also usefull when you have default scope in your model. eg: default_scope -> { order(created_at: :desc) }
arel_table order by
More objected way how to achieve ORDOR BY .... DESC is like this :
class User < ActiveRecord::Base
has_many :status_changes
def latest_status_change
status_changes
.order(StatusChange.arel_table['created_at'].desc)
.first
end
end
class StatusChange < ActiverRecord::Base
belongs_to :user
end
resulting in:
SELECT "status_changes".* FROM "status_changes" WHERE "status_changes"."user_id" = 1 ORDER BY "status_changes"."created_at" DESC
Benefits:
- you are strictly bound to Modelclass name => renaming table in model will not break the sql code (of if it will, it will explicitly break the syntax on Ruby level, not DB level)
- you still have the benefit of explicitly saying what table.column the order should be
- easier to re-factor parts to Query Objects