views:

94

answers:

4

My rails app produces XML when I load /reports/generate_report.

On a separate page, I want to read this XML into a variable and save it to the database.

How can I do this? Can I somehow stream the response from the /reports/generate_report.xml URI into a variable? Or is there a better way to do it since the XML is produced by the same web app?

Here is my generate_report action:

class ReportsController < ApplicationController
  def generate_report
    respond_to do |format|
      @products = Product.all
      format.xml { render :layout => false }
    end
  end
end

Here is the action I am trying to write:

class AnotherController < ApplicationController
  def archive_current
    @output = # get XML output produced by /reports/generate_report
    # save @output to the database

    respond_to do |format|
      format.html # inform the user of success or failure
    end
  end
end

Solved: My solution (thanks to Mladen Jablanović):

@output = render_to_string(:file => 'reports/generate_report.xml.builder')

I used the following code in a model class to accomplish the same task since render_to_string is (idiotically) a protected method of ActionController::Base:

av = ActionView::Base.new(Rails::Configuration.new.view_path)
@output = av.render(:file => "reports/generate_report.xml.builder")
+1  A: 

What I typically do in this type of situation is to create a separate module/class/model to generate the report (it could even potentially be right in the Product model). This separate component could be in app/models or it could be in lib. In any case, once you have it extracted you can use it anywhere you need it. The controller can call it directly. You can generate it from the console. You can have a cron job generate it. This is not only more flexible, but it also can help smooth out your request response times if the report becomes slow to generate.

Since you are using a template it's understandable that the controller route is convenient, but even if you have to include some kind of ruby templating system in your auxiliary lib, it's still probably going to be less hassle and more flexible then trying to go through the controller.

dasil003
+1  A: 

Perhaps you could extract your XML rendering logic to a separate method within the same controller (probably a private one), which would render the XML to a string using render_to_string, and call it both from generate_report and archive_current actions.

Mladen Jablanović
I was able to render the page to a string without any changes using @output = render_to_string(:file => 'reports/generate_report.xml.builder'). Thanks for your help.
titaniumdecoy
+1  A: 

@output = Product.all.to_xml

Kalyan
A: 

I'm sorry, is you question about Xml or about sessions? I mean is the fact that your action generates Xml material to the question? Or do you just want to save the output of the action for latter use?
You said on a "separate" page - you mean on another request? (like after user approved it?) Why do you want to save the output? Because it should be saved exactly as rendered? (for example user can get frustrated if he clicked to save one report and you saved another) Or is this thing expensive to generate?
Or may be, I got it wrong and it's about refactoring?

Art Shayderov