module EchoUploads::PrmFileWriting::ClassMethods
Public Instance Methods
echo_uploads_configure_prm_file_writing(attr, options)
click to toggle source
# File lib/echo_uploads/prm_file_writing.rb, line 17 def echo_uploads_configure_prm_file_writing(attr, options) define_model_callbacks :echo_uploads_write_prm # Save the file and the metadata after this model saves. after_save do |model| @echo_uploads_prm_files_saved ||= {} if (file = send(attr)).present? and @echo_uploads_prm_files_saved[attr.to_sym] != file run_callbacks :echo_uploads_write_prm do # A file is being uploaded during this request cycle. Further, we have not # already done the permanent file saving during this request cycle. (It's # not uncommon for a model to be saved twice in one request. If we ran this # code twice, we'd have duplicate effort at best and exceptions at worst.) @echo_uploads_prm_files_saved[attr.to_sym] = file if options[:multiple] metas = send("#{attr}_metadatas") else metas = [send("#{attr}_metadata")].compact end # metas is now an array of ::EchoUploads::File instances. The array may # be empty. if metas.any? # Previous permanent file(s) exist. This is a new version being uploaded. # Delete the old version(s). metas.each(&:destroy) end # No previous permanent files exists. The metas array is currently empty or # else contains deleted records. We need to rebuild that array by constructing # (but not yet saving) new EchoUploads::File objects. if options[:multiple] mapped_files = send("mapped_#{attr}") || raise('echo_uploads called with :multiple, but :map option was missing') metas = mapped_files.map do |mapped_file| ::EchoUploads::File.new( owner: model, temporary: false, file: mapped_file ) end send("#{attr}_metadatas=", metas) elsif options[:map] mapped_files = send("mapped_#{attr}") metas = [::EchoUploads::File.new( owner: model, temporary: false, file: mapped_files.first )] send("#{attr}_metadata=", metas.first) else metas = [::EchoUploads::File.new( owner: model, temporary: false, file: send(attr) )] send("#{attr}_metadata=", metas.first) end # metas is still an array of the EchoUploads::File instances. If the array was # initially empty (meaning no previous permanent file existed), then it has # since been populated. metas.each do |meta| meta.persist! attr, options end end elsif metas = send("#{attr}_tmp_metadata") run_callbacks :echo_uploads_write_prm do # A file has not been uploaded during this request cycle. However, the # submitted form "remembered" a temporary metadata record that was previously # saved. # Delete any existing metadata record. (It's possible we # were trying to replace an old version of the file, and there were validation # errors on the first attempt.) if options[:multiple] model.send("#{attr}_metadatas").each(&:destroy) elsif old = model.send("#{attr}_metadata") old.destroy end # We need not call persist! here, because the file is already persisted. (Nor # could we call it, because persist! requires an # ActionDispatch::HTTP::UploadedFile.) Mark the metadata record as permanent # and set its owner. metas.each do |meta| meta.owner = model meta.temporary = false meta.expires_at = nil meta.save! end if options[:multiple] send("#{attr}_metadatas=", metas) else send("#{attr}_metadata=", metas.first) end end end end end