code: def persist!(attr, options)
        unless(
          file.is_a?(ActionDispatch::Http::UploadedFile) or
          file.is_a?(Rack::Test::UploadedFile)
        )
          raise(
            "Expected #file to be a ActionDispatch::Http::UploadedFile "+
            "or Rack::Test::UploadedFile, but was #{file.inspect}"
          )
        end
        
        # Configure and save the metadata object.
        self.key = options[:key].call file # Normally, this is .default_key_proc.
        self.owner_attr = attr
        self.original_extension = ::File.extname(file.original_filename)
        self.original_basename = ::File.basename(file.original_filename, original_extension)
        self.size = file.size
        compute_mime! options
        if options[:storage].is_a? String
          self.storage_type = options[:storage]
        else
          self.storage_type = options[:storage].name
        end
        save!
      
        # Write the file to the filestore. It's possible that #file is an instance of
        # EchoUploads::MappedFile, which is a subclass of
        # ActionDispatch::Http::UploadedFile.
        if file.is_a?(ActionDispatch::Http::UploadedFile)
          storage.write key, file.tempfile, self
        else
          storage.write key, file, self
        end
        
        # If we mapped the files, they were temporarily written to tmp/echo_uploads.
        # Delete them.
        if file.is_a?(::EchoUploads::MappedFile) and ::File.exists?(file.path)
          ::File.delete file.path
        end
      
        # Prune any expired temporary files. (Unless automatic pruning was turned off in
        # the app config.)
        unless (
          Rails.configuration.echo_uploads.respond_to?(:prune_tmp_files_on_upload) and
          !Rails.configuration.echo_uploads.prune_tmp_files_on_upload
        )
          self.class.prune_temporary!
        end
      end
docs: Pass in an attribute name, an ActionDispatch::Http::UploadedFile, and an options hash.
   Must set #file attribute first.