2013-05-16 46 views
0

我使用的Roo的寶石導入Excel文件,CSV文件等時袋鼠「文件不存在」錯誤導軌 - 使用延遲招聘

代碼的偉大工程一)在我的本地盒或沒有延遲的工作,和b)在沒有延遲工作的Heroku上。不幸的是,當在Heroku上運行時,如果我使用延遲作業,它會失敗。

這是細節。

控制器:

def importdo 
    fileimport = Fileimport.new 
    fileimport.file_name = params[:file].original_filename 
    fileimport.file_path = params[:file].path 
    fileimport.save 
    fileimportid = fileimport.id 
    Building.delay.import(fileimportid) 
    redirect_to buildings_path, notice: "Buildings import started . . . you will receive an email upon completion." 
end 

fileimport只是我用來跟蹤的文件名和文件路徑表(我試圖通過這些作爲PARAMS而是試圖哈希轉換爲YAML時DelayedJob總是有問題,所以我只是傳入記錄ID)。這也給了我跟蹤我在表格中導入的好處。

這裏是我進口類方法:

def self.import(fileimportid) 
    fileimport = Fileimport.find(fileimportid) 
    file_name = fileimport.file_name 
    file_path = fileimport.file_path 
    newcount = 0 
    updatecount = 0 
    updating = false 
    Building.acts_as_gmappable :process_geocoding => false 
    spreadsheet = open_spreadsheet(file_name, file_path) 
    header = spreadsheet.row(1) 
    (2..spreadsheet.last_row).each do |i| 
     row = Hash[[header, spreadsheet.row(i)].transpose] 

     if zip = row["zip"].to_i.to_s 
      if zip.length > 5 
       zip = zip.first(5) 
      end 
     else 
      raise "zip not valid" 
     end 

     if building = find_by_address_and_zip(row["address"], zip) 
      updating = true 
     else 
      building = Building.new 
     end 
     #building.name = row["name"] 
     building.zip = zip 
     building.address = row["address"] 
     building.city = row["city"] 
     building.save! 
     if updating 
      updatecount += 1 
     else 
      newcount += 1 
     end 
     updating=false 
    end 
    Building.acts_as_gmappable :process_geocoding => true 

    subject = "Your Building Import Completed Successfully!" 
    body = "Your Building Import completed successfully!\n\n" + newcount.to_s + " buildings were created.\n" + updatecount.to_s + " buildings were updated." 

    require 'rest_client' 

    RestClient.post MAILGUN_API_URL+"/messages", :from => "obfuscated", :to => "obfuscated", :subject => subject, :text => body 

end 

def self.open_spreadsheet(file_name, file_path) 
    case File.extname(file_name) 
     when ".csv" then Roo::Csv.new(file_path, nil, :ignore) 
     when ".xls" then Roo::Excel.new(file_path, nil, :ignore) 
     when ".xlsx" then Roo::Excelx.new(file_path, nil, :ignore) 
    else 
     raise "Unknown file type: #{file_name}" 
    end 
end 

這裏是我的文件輸入格式:

<% provide(:title, 'Import Buildings') %> 
<div class="row"> 
    <aside class="span4"> 
     <section> 
      <h1> 
       Import Products 
      </h1> 
      <%= form_tag importdo_buildings_path, multipart: true do %> 
       <%= file_field_tag :file %> 
       <%= submit_tag "Import" %> 
      <% end %> 
     </section> 
    </aside> 
</div> 

的路線是這樣的:

resources :buildings do 
    collection { post :importdo } 
end 

無論如何,像我說過,在我的盒子上工作很好(無論是否有延遲工作)。只有在沒有延遲工作的情況下才能在Heroku上工作(即我必須取出.delay)。這是我收到的特定錯誤(錯誤發送給我,我用一個觀察者檢查延遲時::招聘節省了記錄,並檢查last_error):

file /tmp/RackMultipart20130516-13-7li3o7 does not exist 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/excel.rb:26:in `block in initialize' 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/generic_spreadsheet.rb:579:in `block in make_tmpdir' 
/app/vendor/ruby-1.9.3/lib/ruby/1.9.1/tmpdir.rb:83:in `mktmpdir' 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/generic_spreadsheet.rb:578:in `make_tmpdir' 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/excel.rb:19:in `initialize' 
/app/app/models/building.rb:84:in `new' 
/app/app/models/building.rb:84:in `open_spreadsheet' 
/app/app/models/building.rb:39:in `import' 

我最初的想法是,這只是一個Heroku文件系統的東西,但後來我認爲沒有delayed_job也不行。我的另一個想法是,因爲它是異步的,也許它是一個時間問題(也許臨時文件或者還沒有或者不存在了)。

任何想法,不勝感激。

+0

我沒有用在Heroku DJ,但我已經使用Resque - 我必須確保工作人員已經分手了,你有沒有使用dynos來處理Delayed Job工作? – jbnunn

+0

我正在使用無工作模式,並且DelayedJob正在運行,因爲那是給我的錯誤,我可以嘗試關閉無工作並且只需要工人準備好的情況下,它是一個時間的事情。 – bcb

回答

0

你最初的想法是正確的。這是你的問題背後的Heroku文件系統。即只讀規則!

當您將文件發送到Heroku時,它將存儲在臨時文件夾中,並僅在此一個請求期間可用。它的工作原理沒有delayed_job,因爲你在一個請求和文件可用期間完成了你的工作。

但是,當請求結束並因此文件被刪除時,delayed_job將單獨完成。

最簡單的解決辦法是把文件中的一些雲存儲(我用的S3和carrierwave爲此