One the first cool tricks probably everyone learns when learning Ruby are the range tricks.

(0..5).toa #=> 0, 1, 2, 3, 4, 5.toa #=> [0, 1, 2, 3, 4]

So I was looking to "alpha paginate" my user list in a Rails app. It was already paginated (by another team member of mine) with the pagination helper, but that's useless if I wanted to find a user with the last name beginning with L.

I've seen an alpha paginator out there, but I just couldn't help thinking that it was excruciatingly simple to implement my own.

I took a look at the Ruby, Range class, I figured if the Ruby creators were slick enough to give us cool things like (0..5), why not something like ('A'..'Z')? Well, sure enough, it's in there.

http://www.ruby-doc.org/core/classes/Range.html

Have I mentioned how much I love Ruby?

The first thing I did was write a helper method in applicationhelper.rb so that I could use this anywhere in my Rails app:

def alphalinks(action)
 returntext = '[ '
  ('A'..'Z').toa.each do |letter|
   returntext = returntext + linkto(
    "#{letter} ", 
    :action => action, 
    :id => letter)
   end
return return
text + ' ]' end
I figured it would be nice to have a single method call that generates all the links, and allows me to set the controller method that's called when a user clicks one of the links.

Then in the view, I added this line:

<%= alpha_links('list') %>

Now on the view I have a nifty block that looks like this: {% highlight %} [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ]

where each letter is a link to: /user/list/A or /user/list/B etc etc.

Finally, I modified the "list" controller method as follows:

def list
 if params[:id].nil?
  alpha = 'A%'
 else
  alpha = params[:id] + '%'
 end

@users = User.find( :all, :order => 'lastname',
:conditions => ["last
name like ?", alpha])

end

Oops! As DHH used to say. My alpha pagination is done.

Note that ActiveRecord will sanitize the conditions hash in the example above, to avoid SQL inject attacks. It's worth mentioning that if I wrote that line like so:

 :conditions => "last_name like '#{alpha}%'")
ActiveRecord would NOT sanitize it and SQL could very easily be injected right from the URL!


Published

2009-05-07

Categories


Tags