Rails: Sorting a query by params?

ruby, ruby-on-rails

Solution

I’d use a named scope for providing the default order (available since Rails 2.1).

You’d add the scope in your Post model:

named_scope :ordered, lambda {|*args| {:order => (args.first || 'created_at DESC')} }

Then you can call:

@posts = Post.ordered.paginate :page => params[:page]

The example above will use the default order from the `named_scope` (`created_at DESC`), but you can also provide a different one:

@posts = Post.ordered('title ASC').paginate :page => params[:page]

You could use that with Romulo’s suggestion:

sort_params = { "by_date" => "created_at", "by_name" => "name" }
@posts = Post.ordered(sort_params[params[:sort]]).paginate :page => params[:page]

If `params[:sort]` isn’t found in `sort_params` and returns `nil` then `named_scope` will fall back to using the default order.

Railscasts has some great info on named_scopes.

Problem

I am using running a simple find all and paginating with willpaginate, but I'd also like to have the query sorted by the user. The first solution that came to mind was just use a params[:sort] ``` http://localhost:3000/posts/?sort=created_at+DESC @posts = Post.paginate :page => params[:page], :order => params[:sort] ``` But the problem with his approach is that the query is defaulting as sorting by ID and I want it to be created_at. Is this a safe approach to sorting and is there a way to default to created_at?

Original source