The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Fighting invalid page exceptions

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Patrick Lenz

Posts: 168
Nickname: scoop
Registered: Apr, 2005

Patrick Lenz is the lead developer at freshmeat.net and a contributor to the typo weblog engine
Fighting invalid page exceptions Posted: Jan 21, 2008 3:49 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Patrick Lenz.
Original Post: Fighting invalid page exceptions
Feed Title: poocs.net
Feed URL: http://feeds.feedburner.com/poocsnet
Feed Description: Personal weblog about free and open source software, personal development projects and random geek buzz.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Patrick Lenz
Latest Posts From poocs.net

Advertisement

The will_paginate plugin by Err The Blog feat. Mislav sure is one heck of a must have.

But there’s a tiny thing that’s been bugging me for a while. In December of last year (yeah, last year, been a while..) Mislav committed a change to the plugin that changed the behavior of WillPaginate::Collection to raise an exception if/when the page argument converted to an integer is smaller than 1 (which, quite naturally, any non-integer will eventually end up as).

This change was committed as an attempt to address the invalid SQL generation that happened before (you’d end up with something like LIMIT -10, 10 in the SQL given a non-integer page argument), so this is first and foremost a good thing.

If, however, the only thing that ever makes your page argument a non-integer is during those times where your app is attacked by weird spam bots trying to exploit your PHP (cough) application by shoving random strings down your URIs, things slowly start being annoying if you’re using the exception_notification plugin at the same time and end up with hundreds of exception notifications in your inbox (or, heaven forbid, tickets in your bug tracker) for the WillPaginate::InvalidPage exception on a URL like

http://eins.de/videos?page=http%3A%2F%2Fwww.****.info%2Fimages%2Flebun%2Fisexopo%2F

(Obfuscation mine.)

So what’s an annoyed Ruby hacker to do? Work around it!

The global problem

You can surely go ahead and hack a rescue clause into all of your actions that make use of will_paginate but actually you really shouldn’t. You want these things handled globally.

Initially I was trying to go down the simple route, simply handling it via Rails 2.0’s rescue_from macro:


# app/controllers/application.rb
class ApplicationController < ActionController::Base

  rescue_from WillPaginate::InvalidPage, :with => :invalid_page

  protected

    def invalid_page
      render :text => 'Invalid page requested', :status => 400
    end

end

But there are two problems with this approach.

First of all, I actually wanted to serve a real page instead of an error page. Occasionally someone will mistype a URL or someone will link off of his page erroneously omitting something important and I don’t want him or her looking at an error page. I’d much rather have him look at the first page of the collection he’d like to paginate, which should be closer to the page s/he actually requested.

The second problem is that the application in question isn’t running on Rails 2.0 yet. Yes, I know. Bear with me here.

Hacking the root of the problem

Instead of approaching the problem from the controller side I decided to work on it from the plugin’s perspective. I wanted a default of page = 1 unless a valid page was specified. So I ended up patching WillPaginate::Collection#initialize like this:


# config/initializers/will_paginate_extension.rb
WillPaginate::Collection.send :include, WillPaginate::CollectionExtension

module WillPaginate
  module CollectionExtension

    def self.included(base)
      base.send :alias_method_chain, :initialize, :page_sanitizing
    end

    def initialize_with_page_sanitizing(page, per_page, total = nil)
      page = 1 if page.to_i.zero?
      initialize_without_page_sanitizing page, per_page, total
    end

  end
end

This will simply and quite effectively reset the page to view to 1 if anything that evaluates to a zero integer is passed in.

Okay, enough babbling for such a basic thing. Thanks for reading (if you actually got this far).

Read: Fighting invalid page exceptions

Topic: Mofo - Getting Started w/ Microformats using Ruby - Web 3.0 In Action Previous Topic   Next Topic Topic: Contra--what?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use