Module: EchoUploads::TempFileSaving
- Defined in:
- lib/echo_uploads/temp_file_saving.rb
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
Instance Method Summary collapse
-
#maybe_save_temp_file(attr, options) ⇒ Object
On a failed attempt to save (typically due to validation errors), save the file and metadata.
Class Method Details
.included(base) ⇒ Object
3 4 5 |
# File 'lib/echo_uploads/temp_file_saving.rb', line 3 def self.included(base) base.class_eval { extend ClassMethods } end |
Instance Method Details
#maybe_save_temp_file(attr, options) ⇒ Object
On a failed attempt to save (typically due to validation errors), save the file and metadata. Metadata record will be given the temporary flag.
To deal with the various persistence methods (#save, #create, #update_attributes), and the fact that ActiveRecord rolls back the transaction on validation failure, we can’t just use a convenient after_validation callback. Instead, we have to do some trickery with .alias_method_chain.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/echo_uploads/temp_file_saving.rb', line 14 def maybe_save_temp_file(attr, ) success = yield # Because of the tangled way ActiveRecord's persistence methods delegate to each # other, maybe_save_temp_file sometimes gets called twice. That's unavoidable. To # workaround that issue, we check whether we're calling #save from within #update. @echo_uploads_saving ||= {} @echo_uploads_updating ||= {} unless @echo_uploads_saving[attr] and @echo_uploads_updating[attr] if (file = send(attr)).present? and !success and errors[attr].empty? # A file has been uploaded. Validation failed, but the file itself was valid. # Thus, we must persist a temporary file. # # It's possible at this point that the record already has a permanent file. # That's fine. We'll now have a permanent and a temporary one. The temporary # one will replace the permanent one if and when the user resubmits with # valid data. # Construct an array of EchoUploads::File instances. The array might have only # one element. if [:multiple] mapped_files = send("mapped_#{attr}") || raise('echo_uploads called with :multiple, but :map option was missing') = mapped_files.map do |mapped_file| ::EchoUploads::File.new( owner: nil, temporary: true, expires_at: [:expires].from_now, file: mapped_file ) end else = [::EchoUploads::File.new( owner: nil, temporary: true, expires_at: [:expires].from_now, file: send(attr) )] end # Persist each file. (There might only be one, though.) .each do || .persist! attr, end # Set the attr_tmp_metadata attribute so the form can remember our records. send("#{attr}_tmp_metadata=", ) end end success end |