2011-09-18 120 views
2

此方法效果不錯,但如果我添加的delayed_job是handle_asychronously,我得到can't convert nil into String你如何推遲渲染工作?

def onixtwo 
     s = render_to_string(:template=>"isbns/onix.xml.builder") 
     send_data(s, :type=>"text/xml",:filename => "onix2.1.xml") 
    end 
    handle_asynchronously :onixtwo 

因此,與延遲作業實施顯然具有傳遞PARAMS問題。我試過把這個工作放在一個rake任務中,但render_to_string是一個控制器動作 - 我正在使用一個current_user變量,它只需要在控制器或視圖中引用。那麼......推遲渲染工作的最佳方式是什麼?

/////////更新////////

鑑於我目前有一個三歲的孩子結對編程,我沒有免提調查額外類方法在評論中明智地建議 - 這樣一個快速和骯髒的我嘗試這樣:

def onixtwo 

    system " s = render_to_string(:template=>'isbns/onix.xml.builder') ; send_data(s, :type=>'text/xml',:filename => 'onix2.1.xml') & " 
    redirect_to isbns_path, :target => "_blank", :flash => { :success => "ONIX message being generated in the background." } 

end 

爲什麼它不工作?沒有錯誤信息只是沒有文件產生 - 這是我的情況,當我刪除系統... &

+0

我會親自將渲染邏輯重構爲一個新類並從您的控制器調用它(傳遞給用戶,而不是查找它),然後您將處於更好的背景位置處理它。 – d11wtq

+0

哦,ta。把新的類放在lib中,然後呢?我會去的。 – snowangel

+0

如果你把它放在lib中(這是完全有效的,甚至可能更「正確」),那麼你必須將lib添加到自動加載路徑,並且每當你編輯代碼時你可能必須重新啓動Rack過程。如果你在'app'中創建了一個子目錄(比如'classes'),那麼這個代碼就已經在autoload路徑上,並且會在開發中的每個請求中重新加載:) – d11wtq

回答

0

爲什麼它的價值,這是我所做的,完全繞過render_to_stream。這是在/ lib或應用程序/類(添加config.autoload_paths += %W(#{config.root}/classes進入配置/ application.rb中):

#類/ bookreport.rb

# -*- encoding : utf-8 -*- 
require 'delayed_job' 
require 'delayed/tasks' 

class Bookreport 

    # This method takes args from the book report controller. First it sets the current period. Then it sorts out which report wants calling. Then it sends on the arguments to the correct class. 
    def initialize(method_name, client, user, books) 
    current_period = Period.where(["currentperiod = ? and client_id = ?", true, client]).first 
    get_class  = method_name.capitalize.constantize.new 
    get_class.send(method_name.to_sym, client, user, books.to_a, current_period.enddate) 
    end 
end 

#應用程序/類/ onixtwo.rb

require 'builder' 

class Onixtwo 

    def onixtwo(client_id, user_id, books, enddate) 

    report_name  = "#{Client.find_by_id(client_id).client_name}-#{Time.now}-onix-21" 
    filename   = "#{Rails.root}/public/#{report_name}.xml" 
    current_company = Company.where(:client_id => client_id).first 

    File.open(filename, "w") do |file| 

    xml = ::Builder::XmlMarkup.new(:target => file, :indent => 2) 
    xml.instruct!(:xml, :version => "1.0", :encoding => "utf-8") 
    xml.declare! :DOCTYPE, :ONIXMessage, :SYSTEM, "http://www.editeur.org/onix/2.1/03/reference/onix-international.dtd" 
    xml.ONIXMessage do 
     xml.Header do 
     #masses of Builder code goes here... 
    end 
    end #of file 
    xmlfile = File.open(filename, "r") 
    onx  = Onixarchive.new(:client_id => client_id, :user_id => user_id) 
    onx.xml = xmlfile 
    onx.save! 

end #of method 
handle_asynchronously :onixtwo 

end #of class 

從這樣的觀點調用:

= link_to("Export to ONIX 2.1", params.merge({:controller=>"bookreports" , :action=>:new, :method_name => "onixtwo"})) 

通過這樣的控制器:

class Books::BookreportsController < ApplicationController 
#uses Ransack for search, hence the @q variable 
    def new 
    @q    = Book.search(params[:q]) 
    @books   = @q.result.order('pub_date DESC')  
    method_name  = params[:method_name] 
    Bookreport.new(method_name, @client, @user, @books) 
    redirect_to books_path, :flash => {:success => t("#{method_name.to_sym}").html_safe} 
    end 

end