你如何延迟渲染工作?

时间:2011-09-18 13:36:52

标签: ruby-on-rails xml delayed-job

此方法正常,但如果我添加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

为什么不起作用?没有错误信息只是没有文件产生 - 当我删除系统时就是这种情况......&

1 个答案:

答案 0 :(得分:0)

对于它的价值,这就是我所做的,完全绕过render_to_stream。这是在/ lib或app / classes中(将config.autoload_paths += %W(#{config.root}/classes添加到config / application.rb中):

#classes / 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