Skip to content

Instantly share code, notes, and snippets.

@adamcooper
Created November 8, 2010 16:53
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save adamcooper/667933 to your computer and use it in GitHub Desktop.
class ModelFile < ActiveRecord::Base
has_attached_file :file,
:url => "/model_files/:id/download",
:path => ":rails_root/secure_files/:class/:id_and_version/:style/:basename.:extension",
:keep_old_files => true # save old versions around..
# This returns the actual path of the file for the current_version of this file
def versioned_file_path(from_version = nil)
current_version = version
# we need to set the @version because the file.path will use that version in the path interpolation
@version = version_for_file_path(from_version)
file_path = file.path
# reset it back to the current version because we want to keep the version alone
@version = current_version
file_path
end
protected
# Helper method for versioned_file_path
# this is useful to find the version of when the file content was actually stored on disk
# this is needed because if something else changes later, then the version will increase but the file
# will actually be under and old version.
def version_for_file_path(from_version = nil, to_version = 1)
from_version ||= version
return 1 if versions.empty?
versions.between(from_version, to_version).each do |past_version|
return past_version.original_number if past_version.modifications.include?("file_updated_at")
end
return 1
end
class ModelFilesController < ActiveRecord::Base
def download
@collaboration_file.revert_to(params[:version].to_i) if params[:version].present?
send_file(@collaboration_file.versioned_file_path, :type => @collaboration_file.file_content_type)
end
end
This is a brief description of how to get VestalVersions and Paperclip to play nicely.
The paperclip_initializer.rb extends paperclip for a new option :keep_old_files which means that paperclip won't remove the file when a new file is uploaded. In order for this to work, the model also needs to have to have specific settings:
#1. The version needs to be included in the file path
#2. A method to get the actual path to the file. (The file may not be at the current version)
You can view both these settings in the model_files.rb file below.
Note: If you dealing with public files then you will need to include the :id_and_version option in the :url and :path. Then in the view you need to reference the model_file.versioned_file_path.
Paperclip.interpolates(:id_and_version) { |attachment,style| "#{attachment.instance.id}/#{attachment.instance.version}" }
module Paperclip
class Attachment
# override the save to hack in to keep files around
def save
flush_deletes unless @options[:keep_old_files]
flush_writes
@dirty = false
true
end
end
# keep files around after destroy
module InstanceMethods
def destroy_attached_files
Paperclip.log("Deleting attachments.")
each_attachment do |name, attachment|
attachment.send(:queue_existing_for_delete)
attachment.send(:flush_deletes) unless attachment.options[:keep_old_files]
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment