Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Sorting large datasets
Ruby
Branch: master
Pull request Compare This branch is 76 commits behind mynameisrufus:master.

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.document
.gitignore
.watchr
Gemfile
LICENSE
README.rdoc
Rakefile
sorted.gemspec

README.rdoc

sorted

Sorted is a simple object that will take an sql order string and a url sort string to let you sort large datasets over many pages (using will_paginate) without loosing state.

Using Rails master it will create a sorted scope and a two view helpers

Example

Gemfile

gem sorted

View

link_to_sorted "Email", :email

This will make a url like this:

http://myapp/users?sort=email_asc

or on the next page load when you then sort by something else.…

http://myapp/users?sort=name_asc!email_asc

Model

This will initially sort by email ascending:

@users = User.sorted(:order => "email ASC", :sort => params[:sort]).paginate(:page => params[:page])

Or you can just clone the example app github.com/mynameisrufus/sorted_app.

If you want to sort by a belongs_to relationship, just provide sort order as “RELATIONS.COLUMN ASC|DESC” where RELATIONS is the name of the relationship table and COLUMN is an attribute in that table. For example, assuming the User model belongs_to a :company.

@users = User.sorted(:order => "companies.name asc", :sort => params[:sort]).paginate(:page => params[:page])

Presentation

You might want to roll your own link_to_sorted method to use jQuery ui css classes for example, all you need is the sorted object.

def link_to_sorted(name, order)
  sorter    = sorted(order)
  css_class = case sorter.to_css
              when "sorted asc"
                "ui-icon ui-icon-triangle-1-n"
              when "sorted desc"
                "ui-icon ui-icon-triangle-1-s"
              when "sorted"
                "ui-icon ui-icon-carat-2-n-s"
              end
  link_to(content_tag(:span, nil, {:class => css_class}) + name.to_s, sorter.params)
end

Tables are best displayed with alternating shades for each row, so put this in your helper:

def odd_even
  @odd_even ||= 0
  @odd_even += 1
  (@odd_even % 2) == 1 ? 'odd' : 'even'
end

Then in your table do something like this:

<tr class="<%= odd_even %>">

Rails 2.3.x

This gem works with rails 2.3.x but you will have to roll your own scope and view helper.

Here is the named scope for your model(s):

named_scope :sorted, lambda { |params|
  { :order =>  Sorted::Sorter.new(params[:order], {:sort => params[:sort]}).to_sql }
}

and the the application helper methods:

def sorted(order)
  Sorted::Sorter.new(order, (request.get? && !params.nil?) ? params.dup : nil).toggle
end

def link_to_sorted(name, order)
  sorter = sorted(order)
  link_to(name, sorter.params, {:class => sorter.to_css})
end
Something went wrong with that request. Please try again.