File versioning in Ruby on Rails with Paperclip & acts_as_versioned

This short tutorial shows you how to manage file versioning in Ruby on Rails by making Paperclip falling in love with acts_as_versioned. Paperclip & acts_as_versioned are plug-ins for Ruby on Rails: Paperclip manages file upload, acts_as_versioned enables models versioning.

Patch Paperclip

I patched Paperclip to keep old files when a new revision is saved. A fork of Paperclip adding the option keep_old_files to make Paperclip working with acts_as_versioned is available here: http://github.com/pcreux/paperclip/tree/master. You can install it running:

script/plugin install pcreux_paperclip

Update your Paperclip + acts_as_versioned model

Just three things to do:

  1. update the url & path to store your files by ‘version’
  2. set the option keep_old_files to true when a new version get saved
  3. add the interpolation of :version
class Document < ActiveRecord::Base
  has_attached_file :attachment,
                    :url => "/system/attachments/:id/:version/:style/:basename.:extension",
                    :path => ":rails_root/public/system/attachments/:id/:version/:style/:basename.:extension",
                    :keep_old_files => :version_condition_met?
                    
  acts_as_versioned
  
  Paperclip.interpolates :version do |attachement, style|
    attachement.instance.version.to_s
  end
end

I hope it helps. :)

Post to Twitter

. Bookmark the permalink. Both comments and trackbacks are currently closed.
  • http://unorganized.net/ Eike Bernhardt

    Thanks!
    Exactly what I was looking for.

  • Johnny H

    Hey Philippe, thanks for sharing this – much appreciated. Keep up the good work!!!

  • andy

    have you requested a pull back into Paperclip?

    This patch would be a useful addition.

  • andy

    also, have you seen this Paperclip fork?

    http://github.com/alainravet/paperclip/commit/0943fa3a82447329ebaff4ae217a77fe8236dadb

    he does the same feature, differently – not sure which approach is better

    oddly, you both added the same comment to ‘lib/paperclip.rb’ – how did that happen?

    • http://pcreux.com Philippe Creux

      Hey Andy, I requested a pull back into Paperclip a while ago. I gonna request again. I also saw this Paperclip fork while working on mine – I guess this comment just stayed in my mind. :)

  • andy

    Hi Phillipe,

    I pull your changes into my fork of paperclip and pushed it to gemcutter as “paperclip_with_versions”

    “http://gemcutter.org/gems/paperclip_with_versions”

    Don’t mean to step on your toes here, but we needed this gem’d for our project mgmt.

    I used your example and got this working with acts-as-audited.

    Thanks

    • http://pcreux.com Philippe Creux

      Hey Andy,

      that’s great. Happy to know it helped you.

      Cheers

  • Imtiaz Ahmed

    How do you use this

    set the option keep_old_files to true when a new version get saved
    Where do we update the keeps_old_file

    • http://pcreux.com Philippe Creux

      Check the line 5 of the code sample above.

      :keep_old_files => :version_condition_met?

  • Brett

    Great post! Is this Rails 3 friendly. Also, has this been updated with all the latest paper_clip updates?

    • http://eggsonbread.com Philippe Creux

      Hey Brett,

      The patch hasn’t been updated since then. My change where put together in this commit. Check it out, you might apply the same changes to the latestversion of paperclip. :)

  • Brett

    How do you actually show the image of a previous version? Doing “image_tag(version.photo.photo(:thumb))” always shows the most recent version. thanks

  • Will Koehler

    There’s a new option that tells paperclip to preserve old attachments:

    https://github.com/thoughtbot/paperclip/commit/65e8d4f6de50732d8e1b
    https://github.com/thoughtbot/paperclip/issues/60

    Simple to use:

    has_attached_file => :attachment,
    :styles => { :thumb => 100×100! },
    :preserve_files => true

    It’s not document yet and took some digging to find so I wanted to share it here.