2014-03-27 69 views
8

我添加了通過Dropbox Chooser將文件從Dropbox上傳到我的網站的功能。 除了一件事情之外,一切正常 - 我不知道如何正確實施Cancel功能。它應該以這種方式工作 - 當你點擊Cancel - 相應的文件面板應該從UI中刪除,並且應該停止從Dropbox上傳。如何取消上傳到Amazon S3的文件?

當用戶點擊Choose from Dropbox並選擇文件並單擊Submit我發起Ajax請求到滑軌,涉及一種方法add_file_via_dropbox。在這種方法中,我得到一個URL的Dropbox文件,通過Paperclip寶石幫助上傳到Amazon S3服務器。

當用戶點擊Cancel我想擺脫部分上傳至S3的文件,該文件將在content.attachment屬性中存儲(成功上傳後)。但是當他點擊Cancel - 文件仍在上傳(否則他不會看到Cancel鏈接),我不知道如何立即刪除它。

我的其他想法是,我可以cancelled屬性簡單地添加到content,然後不顯示任何content其中這樣的屬性== true。但這種方法不會節省我浪費Amazon S3上的空間,所以我應該每天運行一次後臺任務來刪除cancelled附件。 我寧願不把它們保存在S3的第一位。可能嗎?我想將控制器的動作add_file_via_dropbox轉移到後臺作業,所以我一旦收到來自客戶端的cancel ajax請求,我就可以kill。我對這一切有點困惑。你會如何解決這個問題?謝謝。

http://i61.tinypic.com/am9p8n.png

product_form.html.erb

$.ajax({ 

    // Cancel file uploading on client side via jqXHR.abort() 
    // It's quite useless because with 99% probability that request  
    // already was sent to Rails and is processing by appropriate action 

    beforeSend: function(jqXHR, options) { 
    tmpl.find('a').click(function(e) { 
     e.preventDefault(); 
     jqXHR.abort(); 
     $(this).parents('li').remove(); 
    }); 
    }, 
    type: "POST", 
    dataType: "json", 
    url: "<%= add_file_via_dropbox_url %>", 
    data: { product_id: $("#fileupload").data("product_id"), file: dropbox_file }, 
}) 

// When Rails response is returned - update UI with "successful upload state" 
.done(function(json_file) { 
    var done_tmpl = $(tmpl("template-download", json_file)); 
    var li = $(".files_list").find('[data-uuid="' + json_file.uuid + '"]'); 
    li.replaceWith(done_tmpl); 
} 
}) 

product_controller.rb

# This method is called by Ajax request 
def add_file_via_dropbox 
    product = Product.find(params[:product_id]) 

    # Each Product has_many Contents(files) 
    file = params[:file] 
    content = product.contents.build 
    content.attachment_remote_url = file[:url] 
    content.save 

    # Construct json response object for Ajax call 
    json_obj = [] 
    json_obj << {name: content.attachment_file_name, 
       size: content.attachment_file_size, 
       url: content.attachment.url, 
       thumbnailUrl: content.attachment.url, 
       deleteUrl: "#{root_url}profile/products/delete_content/#{product.id}/#{content.id}", 
       deleteType: "DELETE", 
       uuid: file[:uuid]} 

    respond_to do |format| 
    format.json { render json: json_obj } 
    end 
end 

內容。RB

class Content 
    attr_reader :attachment_remote_url 
    has_attached_file :attachment, bucket: ENV['S3_BUCKET_NAME'] 

    def attachment_remote_url=(url_value) 
    self.attachment = URI.parse(url_value) 
    end 
end 

LATER

添加的I更詳細調查回形針是如何工作的:

1)在這行代碼執行

content.attachment_remote_url = file[:url] 

這回形針代碼執行paperclip/.../uri_adapter.rb 哪下載從給定的URL文件(DRO在我的例子PBOX URL),並將其保存在本地(在臨時文件中的Rails服務器)

class UriAdapter < AbstractAdapter 
    def initialize(target) 
    @target = target 
    @content = download_content # <---- 
    cache_current_values 
    @tempfile = copy_to_tempfile(@content) 
    end 

... 

def download_content 
    open(@target) # method from 'open-uri' library 
end 

2)只有當我救我的模型在這裏這個文件就會被推向S3:

content.attachment_remote_url = file[:url] 
content.save # <---- 

回形針save方法將被調用:(paperclip/.../attachment.rb

def save 
    flush_deletes unless @options[:keep_old_files] 
    flush_writes # <----- 
    @dirty = false 
    true 
end 

而且flush_writes然後推動本地文件到S3(paperclip/.../s3.rb

def flush_writes  
    # omitted code  
    s3_object(style).write(file, write_options) # method from `aws-sdk` gem 
    # omitted code     
    end 

所以我拉近我原來的問題這兩個:

1)如何取消呼叫open(@target)時,它已經在行動(文件下載到我的Rails服務器)

2)如何當文件從Rails服務器上傳到S3時,取消對s3_object(style).write(file, write_options)的調用?

+0

沒試過'Rails',也不'亞馬遜S3'。 'done_tmpl'是一個'html''元素嗎?或者,'html''元素內的內容?感謝分享 – guest271314

+0

TMPL(「模板下載」),將業務拓展到的代碼的HTML塊。 – yaru

+0

請參閱帖子。感謝分享。希望這有助於 – guest271314

回答

2

如果該文件仍然上傳到服務器之前的服務器端處理文件到S3,你要喜歡你已經中止連接。即How to cancel/abort jQuery AJAX request?

如果文件上傳到服務器,現在上傳到S3:因爲Ruby不是基於異步,你基本上將不得不讓文件上傳,但由於服務器現在上傳,您客戶端可以在技術上離開頁面。所以我想通過一個唯一的ID回來的時候您的服務器接收的文件,如果用戶仍然點擊取消,然後拍攝的ID後面,並讓您的服務器投票或即cron等環境要刪除的文件。

+0

我不想讓Rails服務器將文件完全上傳到S3,因爲文件可能很大(高達1Gb),並且會花費我流量和金錢。如果用戶在上傳文件時點擊「取消」,則顯示用戶不再需要它,並且我想立即取消文件上傳。任何想法如何做到這一點? – yaru

+0

@ yaru一種可能的方法是用命令+ arg I.e產生一個進程。在PHP中,我會做「php」file-upload-id'「。然後每隔一分鐘運行一次cron以查找DB中的任何刪除請求,然後執行查找/殺死pid的過程。 –

+0

MKN網絡解決方案,請在我的問題中閱讀添加後期部分(剛添加它)。產卵過程對於我的問題仍然是唯一可接受的解決方案? – yaru