# Restful Resource routes with parameters and page caching

**URL:** <https://www.ruby-forum.com/t/restful-resource-routes-with-parameters-and-page-caching/117137>\
**Category:** Rails\
**Created:** [October 13, 2007, 6:31pm UTC](https://www.ruby-forum.com/t/restful-resource-routes-with-parameters-and-page-caching/117137 "2007-10-13T18:31:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lukeredpath](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@lukeredpath](https://www.ruby-forum.com/u/lukeredpath)\
**Post date:** [October 13, 2007, 6:31pm UTC](https://www.ruby-forum.com/t/restful-resource-routes-with-parameters-and-page-caching/117137/1 "2007-10-13T18:31:19Z")

</div>

I’m trying to set up a restful route where an Album resource has a  
singletone Artwork resource. Sounds simple enough:

map.resources :albums do |album|  
album.resource :artwork,  
:controller =\> ‘artwork’, :format =\> ‘jpg’  
end

With the above routing config, /albums/xxx/artwork.jpg works as  
expected.

However, my artwork controller also has an option to resize the image  
if a :size parameter is given. This also works:

/albums/xxx/artwork.jpg?size=100

However, I want to cache the resized artwork using Rails caching.  
Adding caches\_page :show works and the cached file is saved under  
public/albums/xxx/artwork.jpg.

But what about when I specify a size? I want these to be cached  
individually. Specifying size as a query string parameter means the  
size is ignored when caching takes place (it is always stored as  
artwork.jpg). What I really need is to be able to move the size  
parameter into the URL, so it looks something like this:

/albums/xxx/artwork/size.jpg

This would mean page caching does what I want it to do. However I  
cannot see any easy way of moving size into the URL using  
map.resource. I can set up a custom route but any restful url helpers  
take no notice of it. Can anybody help me with this?

---

<div class="post-metadata">

**Author:** ![lukeredpath](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@lukeredpath](https://www.ruby-forum.com/u/lukeredpath)\
**Post date:** [October 13, 2007, 6:40pm UTC](https://www.ruby-forum.com/t/restful-resource-routes-with-parameters-and-page-caching/117137/2 "2007-10-13T18:40:06Z")

</div>

Umm…I’m not a fan of nested resources, so I don’t know how this would  
behave here, but try using path\_prefix

map.resources :albums do |album|  
album.resource :artwork, :controller =\> ‘artwork’, :format =\>  
‘jpg’, :path\_prefix =\> ‘:size’  
end

On 10/13/07, Luke R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> expected.  
> But what about when I specify a size? I want these to be cached  
> take no notice of it. Can anybody help me with this?
> 
> >

–  
Cheers!

- Pratik  
[http://m.onkey.org](http://m.onkey.org)

---

<div class="post-metadata">

**Author:** ![lukeredpath](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@lukeredpath](https://www.ruby-forum.com/u/lukeredpath)\
**Post date:** [October 13, 2007, 7:03pm UTC](https://www.ruby-forum.com/t/restful-resource-routes-with-parameters-and-page-caching/117137/3 "2007-10-13T19:03:28Z")

</div>

I’m not sure that path\_prefix is what I need here; either way, I  
managed to get this working by treating size as another resource under  
artwork. So in essence:

An album has ONE artwork (singleton resource).

map.resources :albums do |album|  
album.resource :artwork  
end

That single piece of artwork can be represented in a number of  
different sizes (could be fixed, but in my case its arbitrary):

map.resources :albums do |album|  
album.resource :artwork do |artwork|  
artwork.resources :size  
end  
end

However, because the controller code to resize the image was so simple  
(it was all abstracted to the model layer), I was able to handle both  
the singleton artwork resource and its various sizes with a single  
ArtworkController#index action:

class ArtworkController \< ApplicationController  
before\_filter :load\_album  
caches\_page :show

def show  
@artwork = Artwork.new(@album, size = params[:id])

```
send_data @artwork.to_blob,
  :disposition => 'inline',
  :type => @artwork.content_type

```

end

private  
def load\_album  
@album = SlimServer::Album.find(params[:album\_id])  
end  
end

The only thing here that is slightly confusing is that the size we  
want arrives as params[:id]; this wouldn’t be so confusing if I was  
using a separate AlbumSizesController I guess so I can live with it  
(hence I’ve added the variable hint to the parameter).

The final routing config, with controller names and formats specified  
is:

map.resources :albums do |album|  
album.resource :artwork, :controller =\> ‘artwork’, :format =\> ‘jpg’  
do |artwork|  
artwork.resources :sizes,  
:controller =\> ‘artwork’, :format =\> ‘jpg’  
end  
end

I can now access the raw unaltered artwork using /album/xxx/  
artwork.jpg and a specific size at /album/xxx/artwork/sizes/xxx.jpg.

Hope this helps anyone with a similar issue.

---

<div class="post-metadata">

**Author:** ![lukeredpath](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@lukeredpath](https://www.ruby-forum.com/u/lukeredpath)\
**Post date:** [October 13, 2007, 7:04pm UTC](https://www.ruby-forum.com/t/restful-resource-routes-with-parameters-and-page-caching/117137/4 "2007-10-13T19:04:39Z")

</div>

Small correction the above post, the following block of code should  
have artwork.resources :sizes (plural).
