Module: CachedUploads
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/cached_uploads.rb
Overview
This module enables you to upload files and persist them in a cache in the event that the form must be redisplayed (e.g. due to validation errors). This module also saves the files to their final location when the record is saved.
The controller is still responsible for the overall workflow. It should use the normal ActiveRecord API, with one addition: If the submission is invalid, the controller must call #write_temporary_files.
The controller (or cron task, or a worker process) should also call .clean_temporary_files from time to time. An easy option is to clean up any time an invalid submission is received.
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
- #delete_permanent_file(file_attr) ⇒ Object
- #write_permanent_file(file_attr) ⇒ Object
- #write_permanent_file_md5(file_attr) ⇒ Object
-
#write_temporary_file(file_attr) ⇒ Object
Writes the temporary file, basing its name on the MD5 hash of the uploaded file.
-
#write_temporary_files ⇒ Object
Saves any configured temporary files.
Instance Method Details
#delete_permanent_file(file_attr) ⇒ Object
22 23 24 25 26 27 28 |
# File 'lib/cached_uploads.rb', line 22 def delete_permanent_file(file_attr) config = self.class.cached_uploads[file_attr.to_sym] prm_path = send config[:prm_path_method] if File.exists?(prm_path) File.delete prm_path end end |
#write_permanent_file(file_attr) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/cached_uploads.rb', line 41 def write_permanent_file(file_attr) config = self.class.cached_uploads[file_attr.to_sym] uploaded_file = send file_attr if uploaded_file.present? # This *won't* execute if we've set the temporary file MD5 attribute instead of the # file attribute. It will only execute if we're uploading the file for the first time. # (Technically, if both the file and the MD5 are present, this would execute. But that # would be an error state.) prm_file_path = send config[:prm_path_method] File.open(prm_file_path, 'wb') do |out_file| uploaded_file.rewind out_file.write uploaded_file.read end elsif send(config[:tmp_md5_attr]).present? # This executes if we've set the temporary file MD5 attribute instead of the file # attribute. This is invoked when the user has submitted invalid data at least once. # In which case we've saved the uploaded data to a tempfile on the server. Now the # user is resubmitting with correct data. (We know it's correct because # #write_permanent_file is triggered by an after_save callback.) tmp_file_path = send config[:tmp_path_method] prm_file_path = send config[:prm_path_method] FileUtils.cp tmp_file_path, prm_file_path end end |
#write_permanent_file_md5(file_attr) ⇒ Object
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/cached_uploads.rb', line 30 def write_permanent_file_md5(file_attr) config = self.class.cached_uploads[file_attr.to_sym] file = send file_attr method = "#{config[:prm_md5_attr]}=" if file.present? and respond_to?(method) file.rewind md5 = Digest::MD5.hexdigest(file.read) send method, md5 end end |
#write_temporary_file(file_attr) ⇒ Object
Writes the temporary file, basing its name on the MD5 hash of the uploaded file. Raises if the uploaded file is #blank?.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/cached_uploads.rb', line 71 def write_temporary_file(file_attr) config = self.class.cached_uploads[file_attr.to_sym] file = send file_attr if file.present? # Read the uploaded file, calc its MD5, and write the MD5 instance variable. file.rewind md5 = Digest::MD5.hexdigest(file.read) send "#{config[:tmp_md5_attr]}=", md5 # Write the temporary file, using its MD5 hash to generate the filename. file.rewind File.open(send(config[:tmp_path_method]), 'wb') do |out_file| out_file.write file.read end else raise "Called #write_temporary_file(:#{file_attr}), but ##{file_attr} was not present." end end |
#write_temporary_files ⇒ Object
Saves any configured temporary files. Controllers should call this method when an invalid submission is received. Does not save a temporary file if the file itself had a validation error.
94 95 96 97 98 99 100 |
# File 'lib/cached_uploads.rb', line 94 def write_temporary_files cached_uploads.each_key do |file_attr| if errors[:file].empty? and send(file_attr).present? write_temporary_file file_attr end end end |