2011-09-18 76 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