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