开发者

How do you delay a rendering job?

This method works OK, but if I add delayed_job's handle_asychronously, I get 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

So re开发者_开发技巧ndering with delayed job is clearly having a problem with params being passed. I've tried putting this job in a rake task but render_to_string is a controller action - and I'm using a current_user variable which needs to be referenced in the controller or view only. So... what's the best way to delay a rendering job?

/////////update////////

Given that I'm currently pair-programming with a toddler, I don't have the free hands to investigate additional class methods as wisely recommended in the comments - so as a quick and dirty I tried this:

  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

Why doesn't it work? No error message just no file produced - which is the case when I remove system ... &


For what it's worth, this is what I did, bypassing render_to_stream entirely. This is in /lib or app/classes (adding config.autoload_paths += %W(#{config.root}/classes into 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

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

Called from the view like this:

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

Via a controller like this:

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 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜