2011-01-25 78 views
0

原名:運行在一個回形針附件的模型方法後,創建或更新(回形針回調似乎不工作)回形針處理器無法找到它的文件

編輯(當天晚些時候) 我想通出我的問題。處理器顯然與更新的文件一起工作,但在處理之後才保存任何文件。我改變了我的Zip :: ZipFile來打開'file'而不是'attachment.path',因爲附件路徑實際上並沒有保存任何東西。這解決了第一個問題。現在我還有其他問題需要追蹤。但下面的答案大部分是正確的。

編輯(2011年1月31日):

所以我採取了建議創建我的執着處理器,該處理器將執行所有必要的行動。到目前爲止,它看起來應該起作用;處理器啓動並顯然執行所有初始化操作。但是,當我得到要訪問上載的zip文件的位置時,出現錯誤,指出無法找到該文件。我的處理器的代碼如下:

class Extractor < Processor 
    attr_accessor :resolution, :whiny 
    def initialize(file, options = {}, attachment = nil) 
     super 
     @file = file 
     @whiny = options[:whiny].nil? ? true : options[:whiny] 
     @basename = File.basename(@file.path, File.extname(@file.path)) 
     @attachment = attachment 
     @instance = attachment.instance 
    end 
    def make 
     # do your conversions here, you've got @file, @attachment and @basename to work with 
     export_path = attachment.path.gsub('.zip', '_content') 

     Zip::ZipFile.open(attachment.path) { |zip_file| 
     zip_file.each { |image| 
      image_path = File.join(export_path, image.name) 
      FileUtils.mkdir_p(File.dirname(image_path)) 
      unless File.exist?(image_path) 
      zip_file.extract(image, image_path) 
      # ..stuff that it does.. 
      end 
     } 
     } 
     # clean up source files, but leave the zip 
     FileUtils.remove_dir(export_path) 


     # you return a file handle which is the processed result 
     dst = File.open result_file_path 
    end 
end 

這裏是錯誤的,我得到的內容:

Zip::ZipError in GalleriesController#create 

File /home/joshua/railscamp/moments_on_three/public/assets/archives/delrosario.zip not found 

Rails.root: /home/joshua/railscamp/moments_on_three 
Application Trace | Framework Trace | Full Trace 

config/initializers/extractor.rb:16:in `make' 
app/controllers/galleries_controller.rb:32:in `new' 
app/controllers/galleries_controller.rb:32:in `create' 

Request 

Parameters: 

{"utf8"=>"✓", 
"authenticity_token"=>"0s4L4MrlqjDTMjzjgkUdvUxeHklZNOIShDhT6fgOICY=", 
"gallery"=>{"name"=>"DelRosario", 
"public"=>"0", 
"owner_id"=>"1", 
"shoot_date(1i)"=>"2011", 
"shoot_date(2i)"=>"1", 
"shoot_date(3i)"=>"31", 
"category_id"=>"1", 
"archive"=>#<ActionDispatch::Http::UploadedFile:0x00000004148d78 @original_filename="delrosario.zip", 
@content_type="application/zip", 
@headers="Content-Disposition: form-data; name=\"gallery[archive]\"; filename=\"delrosario.zip\"\r\nContent-Type: application/zip\r\n", 
@tempfile=#<File:/tmp/RackMultipart20110131-9745-14u347v>>}, 
"commit"=>"Create Gallery"} 

從我可以告訴它尋找合適的地方的文件,但該文件似乎還沒有上傳,但無法訪問它。據我所知,Paperclip在嘗試處理附件之前已足夠聰明,可以知道並等待附件上傳。任何人都可以發現我在這裏做錯了嗎?

非常感謝。

舊的東西:

我正在開發使用Rails 3和回形針照片庫應用程序。管理員可以創建一個圖庫並上傳一個包含一系列圖像的zip文件。

我想什麼發生:

  1. 進入畫廊的信息和zip文件上傳到表單。
  2. 點擊「創建圖庫」按鈕。
  3. 表單文章,圖庫保存和zip文件被上傳。
  4. 上傳zip文件後,運行方法:extract_photos(順便說一句,此代碼 工程)。 4.a.在該方法結束時,zip文件被破壞。
  5. 管理員被重定向到畫廊頁面,其中的所有照片(其中 圖庫has_many照片)。

我試過讓這個工作有幾種不同的方式。

之前,我創建了一個控制器方法,該方法允許管理員單擊運行:extract_photos方法的鏈接。這在我的計算機上工作,但由於某種原因,服務器無法在客戶端的計算機上路由該服務器。所以這是不行的。另外我認爲這是一個醜陋的做法。

最近,我嘗試使用回調方法。 after_save不起作用,因爲它顯然會中斷POST表單,並且文件沒有上傳,並且:extract_photos方法找不到該文件。

我檢查了回形針GitHub的頁面上回調方法,並談到了回調:

前和後處理 步驟之後,回形針回調到 模型有一些回調,允許 模型更改或取消 處理步驟。回調是 「before_post_process」和 「after_post_process」(這和之前的 處理每個附接之後被稱爲 ),並且附接 特定 「beforepost_process」和 「afterpost_process」。該回調 旨在儘可能接近正常 ActiveRecord的回調可能,因此 如果返回false(具體 - 返回nil是不一樣的)在 過濾器前,後處理 一步將暫停。在過濾器不會暫停任何操作後返回 , ,但您可以根據需要訪問模型和 附件。

我使用before_post_process和after_post_process試過,但它無法找到運行過程中的文件,所以很明顯是沒有得到的時候上傳的文件將這些方法獲取調用(我認爲這是奇怪)。另外,當我嘗試beforepost_process和afterpost_process之後,我得到一個NoMethodError。

那麼,如何在創建或更新附件時調用附件的方法,但在文件上傳並放置在正確的位置之後呢?

UPDATE

我嘗試下面的代碼,移動我提取方法的代碼到處理器的化妝方法。我試圖編寫一個處理器的時間比以前更遠了,但它仍然是一個不行。當我嘗試打開上傳的文件進行處理時,該進程會立即拋出異常,並說該文件不存在。命名方案是正確的,並且一切正常,但仍然在進程被觸發之前沒有任何內容被上傳。有誰知道爲什麼會發生這種情況?

回答

2

您可以編寫自己的處理器來完成此操作。

在模型

聲明回形針的東西時,添加自定義處理器

has_attached_file :my_attachment, { 
    :styles => {:original => {:processors => [:my_processor]}} 
    }.merge(PAPERCLIP_SETTINGS) 

然後寫你自己的處理器,並把它配置/初始化:

module Paperclip 
    class MyProcessor < Processor 
    attr_accessor :resolution, :whiny 
    def initialize(file, options = {}, attachment = nil) 
     super 
     @file = file 
     @whiny = options[:whiny].nil? ? true : options[:whiny] 
     @basename = File.basename(@file.path, File.extname(@file.path)) 
     @attachment = attachment 
    end 
    def make 
     # do your conversions here, you've got @file, @attachment and @basename to work with 

     # you return a file handle which is the processed result 
     dst = File.open result_file_path 
    end 
    end 
end 

我用一個自定義的處理器的事類似於你正在做的很多處理和文件轉換的中間,它似乎工作得很好。

+0

你還能訪問父模型和處理器中的所有東西嗎?其中一個主要功能是:使用當前正在提取的文件從庫中構建一系列依賴對象。處理器上的文檔實際上並不存在。 – 2011-01-27 21:55:02