changing :path

37 views
Skip to first unread message

ngw

unread,
Nov 23, 2009, 12:03:13 PM11/23/09
to Paperclip Plugin
Hi guys, I'm trying to use Cloudfront and I need to avoid serving
stale content.
The problem is that I already have a large amount of files saved over
S3, and I was asking myself if someone already solved the problem of
renaming all the old files, adding for example a timestamp.
What's the best way to do it ?

ngw

matt

unread,
Nov 24, 2009, 12:09:37 PM11/24/09
to Paperclip Plugin
I have been through doing this with my app.

In the end I opted NOT to use cloudfront because its such a pain
trying to expire files this way, ie. the URL MUST change.
What I did was put a uuid (random string based on timestamp) attribute
on each model that had an attachment, then I used a paperclip
interpolates method to have the uuid inserted in the path. AND I have
the uuid be regenerated on editing of the file (with a before_create
and after_update method)

before_create :generate_uuid

private
def generate_uuid
self.uuid = Digest::MD5.hexdigest("#{Time.now.utc.to_i}#{rand(2 **
128)}")[0..6]
end

:path => ":class/:uuid/:id/:style/:basename.:extension"

And in config/initializers/paperclip.rb

Paperclip.interpolates :uuid do |attachment, style|
attachment.instance.uuid
end

This worked fine but a problem quickly arose. Since I allow my users
to upload/edit css and js files through paperclip; which can have
references to other (uploaded via paperclip) files in them. So when
the filename (uuid) changed on edit, I found myself having to expire
all references to the file in other files, and doing that expired them
etc. etc. It all got complicated and very messy quickly.

In the end, I've ditched cloud-front, and implemented the above
features using only S3 AND forcing unique filenames (scoped to the
current user) - Also all generated urls were appended with timestamps
- e.g. main.css?34128791 (a common practice, encouraged on Rails)

With this, since the filenames were now unique and didn't change on
edit, I could reference things relatively (rather than using absolute
urls) e.g. in a main.css file I could now have;

background-image: { 'myimage.jpg?32948328' no-repeat }

Since main.css and myimage.jpg resided in the same folder.
And to expired cached client side stores, I just append a new
timestamp on the query string.

Anyway - hope this helps,

m
Reply all
Reply to author
Forward
0 new messages