REST way of doing pagination.

I was having a discussion with a great friend on what "REST way of paginating" means.

Without polluting your minds initially with the ideas we discussed, I'd like to get everyones thoughts as to what this might mean and how you envision it being implemented.

  ~Wayne

Hey,

I see nothing inherently "unRESTful" about pagination in the style people generally do it in rails.

As in: GET /some/resource?page=35 is a perfectly valid action and URL (from a REST perspective) which uniquely describes the resource you are looking for ("page 35 of whatever /some/resource is").

So my answer to your questions would be: "the way it works now".

Perhaps you might give just a *little* background on why you think the current style is not RESTful.

HTH Trevor

Thanks for the response Trevor.

We do not see anything "unRESTful" about it either nor do I view the current system as not RESTful. We were simply wondering if there was something subtle and/or obvious that we were missing pertaining to REST. Our basic view is that the will_paginate method is the best way thus far (that we've seen).

Ah okay,

I assumed that you were implying that pagination as it's done now is not "the REST way of paginating".

Often people talk about whether something is RESTful when in fact they mean something more like RAILSy (pretty urls, the mapping of certain urls to certain actions).

I've had more than a few conversations with people who were trying to eliminate ?param=value from their URLs because they (erroneously, imho) believed the params somehow violated REST.

But I *am* curious to know what ideas came out of the discussion you mentioned.

Trevor

Trevor,

Our discussions finally ended up along the lines of: a RESTful way would, perhaps, be to abstract the pages themselves as a nested resource object. An example:

/posts/4/pages/2

where the pages/2 gets translated into parameters but from the abstract we're saying that it would return an object which is a "set" of posts.

But this was just a half baked concept as we fiddled with the meaning of "REST" in addition to the concept of "pretty url's".

That's not a bad idea. One problem is you don't want them going to a PagesController or anything like that. What about this?

map.resources :posts do |post|   post.pages # sets up /articles/:article_id/pages/:page routes for the articles controller   post.resources :comments end

Weekend plugin challenge!

Hey Rick,

I've already gone through a similar loop (and as it happens, have a plugin that I'm currently running through its paces) for 'canned reports':

map.report_on :sales do |sales|   sales.today #=> /sales/today calls today()   sales.for_year 'during/:year' #=> /sales/during/:year calls for_year() end

It's pretty trivial to do this sort of thing as long as you work within the limitations of the route mapper.

1 the only bit of context passed into your blocks is path_prefix and name_prefix

this means that you don't have access to a :controller option when your pages() method (or my report_on() method) is called. And implicitly passing the :controller in the scope would be interpreted as manually overriding the controller for other methods like resources().

2 for map.resources, the path_prefix given to your block is for the *member* and not the collection.

3 there's little point trying to overcome #2 because by the time your block executes it's too late to define any /pages urls for the collection. As in /posts/pages will be picked up by the route for /posts/:id

I've experimented with a hack or two that tried to address #2 by changing with_options to pass more than one OptionMerger but ultimately it's pointless because of #3.

Wayne, I'd be happy to let you see my code before it's released (if indeed it ever does get released), just send me a note off-list.

Regards, Trevor

Sorry, that probably came across as "you can't get there from here" - which is clearly not the case. Nothing is impossible, I'm just saying that overcoming the limitations I mention would probably mean non-trivial tinkering with how the mapper and/or resource() and resources() behave.

Trev

Excellent, I wasn't aware of that!

Is this new in edge or something? It looks like you're about to define a named route called 'pages' but then you never specify the route.

Jeff

It's something I made up. I don't intend to write it anything.

Has anyone made a plugin out of this?

/posts/4/pages/2

I'm not partial to this way of referencing pages, if it refers to a changing collection. Slashes indicate a fairly "hard" definition of a path to some resource. If you add items to the collection and the result set of each page changes, this URL doesn't refer to the same thing. I think of the page parameter more like a search (i.e. filtering) query in this case.

Just another opinion...

--Andrew Vit

GoogleGroups said my post was successful, but it's been several hours, and it isn't showing up. I'm going to chance a double post here.

What about a URL with a little more semantic meaning? Like /posts/Cogaidhean/?start_with=2006_9_17&return_count=10 or something? It just seems so much more 'discoverable' that way.

Ron

I wouldn't mind if the plugin just did:

/posts/2?p=2

maybe i'll make it when i have time

Lance,

why do you need a plugin for that?

post_path(:id => 2, :stuck_out_tongue: => 2) #=> /posts/2?p=2

Am I missing something?

Trev

Not sure if I'm just being lazy or if it would be practical to have a plugin that automatically used the query provided in your index action and auto paginated that.. am I just being lazy? :slight_smile:

Well,

lazy can be a positive thing :slight_smile:

Give it a shot, there might be something interesting there.

Trev

Did you check out the will_paginate plugin? That's almost exactly what you're describing. There's not really a way to 100% automate the pagination, but will_paginate comes close.

Jeff