rails: store output of XML builder in database - ruby-on-rails

In a rails (2.3) app I have been building, I have an XML builder that outputs neat XML. I need to take a snapshot of this XML and store it in the database (or file) upon a certain user action.
How do I get the output of the xml builder view from in the middle of another action?
This code causes a deadlock in a single threaded application...
uri = URI.parse("http://localhost:3000")
response = Net::HTTP.start(uri.host, uri.port) {|http|
http.head('/xmliwanttoarchive.xml')
}
Not sure how to approach this one.. Cheers.

The above is the wrong way to go about invoking the xml builder.
I overrode the to_xml method instead of using an xml.builder view
def to_xml(options={})
if options[:builder]
build_xml(options[:builder])
else
xml = Builder::XmlMarkup.new
xml.instruct!
build_xml(xml)
end
xml
end
def build_xml(xml)
xml.foo("id" => id, "title" => title) do
xml.group("id" => group.id, "name" => group.name)
xml.bars do
bar.each do |session|
xml.bar("id" => bar.id, "session_time" => bar.important_thing)
end
end
end
Now it can be easily used from within the code and from an action

Related

Rails and XML requests

In my Rails 4 app I am dealing with an API that only handles XML (yes I wish it was JSON too).
I have to make a POST request and the XML string should be stored in a parameter called xmlRequestString.
The XML structure for the POST data is:
<?xml version="1.0" encoding="UTF-8"?>
<GetProperties>
<Auth>
<VendorId>UserID</ VendorId>
<VendorPassword>Password</VendorPassword>
</Auth>
</GetProperties>
As I have never even touched XML before could someone show me how I would actually post this data.
Would something like this be a good way of going about it (borrowed from here: Submitting POST data from the controller in rails to another website)?
require "uri"
require "net/http"
xml = 'xml string can go here'
params = {'xmlRequestString' => xml}
Net::HTTP.post_form(URI.parse('urlendpoint'),params)
You can save this as a template, with instance variables like in a regular html.erb template. Or, you could have it as a method in a model. Either way, you're using something that takes some dynamic data and returns you a text string, that has the xml in it. Then, in your controller, render out the template, or call the method (if you put it in a model) and post it to the api.
#Template method of generating xml
#app/views/properties/get_properties.rxml
xml.instruct! :xml, :version=>"1.0", :encoding => "UTF-8"
xml.GetProperties do
xml.Auth do
xml.VendorId do
<%= #user_id %>
end
xml.VendorPassword do
<%= #password %>
end
end
end
Then, in a controller, call the api:
#user_id = "foo"
#password = "bar"
xml_string = render :template => "properties/get_properties.rxml", :layout => false
http = Net::HTTP.new("www.the-api-website.com")
response = http.post("/path/to/call/the/api", xml_string)

How to serve a static JSON file in rails?

I have a file on my server that's outside of my app directory. It's a text file that holds a json object, /path/to/data.json.
What's the simplest way to serve this file in Rails, e.g. to return it in response to a GET request?
Here's what I've tried so far, inspired by this answer and others. (This may be way off-base -- I'm new to rails.)
added this line to routes.rb
resources :data
Wrote the following data_controller.rb
class DataController < ApplicationController
#data = File.read("/path/to/data.json")
def index
render :json => #data
end
end
This doesn't work. When I direct my browser to http://myserver.com/data.json I just see "null" instead of the data.json file.
Any idea what I'm doing wrong?
I think this is a scope issue; your outer #data is not the same as the #data in a method. That is, you can't use instance variables as expected outside of methods because there is no instance yet.
It should work if you use a class variable, eg
##data = File.read("/path/to/data.json")
then
render :json => ##data
Put it in public/assets/javascripts. Or app/assets/javascripts. The server may even return the correct content-type.
put data.json file into your project directory ( for example public/data.json)
#data = File.read("#{Rails.root}/public/data.json")
At last but not least render :json => #data
You can also do it in one line, e.g.
render :file => '/path/to/data.json',
:content_type => 'application/json',
:layout => false

How to format a result going to JSON from a rails controller?

In rails, lets say I do this:
def retrieveAllWidgets
widgets = Widgets.all(:conditions => "status = 1")
render :json => widgets
end
in a rails controller. The json response will contain all the attributes of widget that are exposed. The issue is the widgets have a price, and before sending the JSON response back to the client I want the price to be formatted with number_with_currency.
I think I could do this:
def retrieveAllWidgets
widgets = Widgets.all(:conditions => "status = 1")
formattedWidgets = []
widgets.each do |widget|
formattedWidgets.push({"id" => widget.id,
...
"price" => number_to_currency(widget.price)
}
)
end
render :json => formattedWidgets
end
But is that the way to do it? Is there anyway of appropriately formatting without looping over all results? number_to_currency is really useful, but is I think best used in the view but thats not appropriate for my needs as a JSON response. I could be doing things entirely wrongly. The point is that it's a JSON response only, that is then used in a one page app.
As I understand it you have to format the data in the view, RetrieveAllWidgets.json.erb.
You would have to pass in #widgets. The view will return the json after you format it.
Having a lookig at http://api.rubyonrails.org/ and searching erb may help

How do you output JSON from Ruby on Rails?

I'm looking to have a model that gets created / updated via AJAX. How do you do this in Ruby on Rails?
Also, more specifically: how do you output JSON in RoR?
def create
response = {:success => false}
#source = Source.new(params[:source])
if #source.save
response.success = true
end
render :json => response.to_json
end
All you need to do is call render :json with an object, like so:
render :json => my_object
For most objects, this will just work. If it's an ActiveRecord object, make sure to look at as_json to see how that works. For your case illustrated above, your hash will be transformed to json and returned.
However, you do have an error: you cant access the success key via response.success -- you should instead do response[:success]
jimothy's solution is really good butI believe it isn't scalable in the long term. Rails is meant to be a model, view, and controller framework. Right now JSON is cheated out of a view in default rails. However there's a great project called RABL which allows JSON view. I've written up some arguments for why I think it's a good option and how to get up and running with it quickly. See if this is useful for you: http://blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl/
#source = Source.new(params[:source])
respond_to do | f |
f.html {
# do stuff to populate your html view
# maybe nothing at all because #source is set
}
f.any(:xml, :json) {
render request.format.to_sym => #source
}
end

Saving XML files with Rails

im working on a Rails project that should create XMl files, or to be more specific
use existing XMl templates and put content from the database in it.
So i dont need to create the xml structure, basically just rendering a template with content.
What would be the smartest way to do that?
So far i have a file.xml.erb in my layout folder
and i have a custom route "/renderXML" that does
def renderXML
#reading_question = ReadingQuestion.find(params[:id])
render :file => 'layouts/question.xml'
end
This works, but i also want to save the file, not only show it (actually viewing it is not really needed).
For saving i found this
File.open('fixed.xml','w'){|f| f.write builder.to_xml}
How do i access the rendered file and save it with some method like above?
Perhaps something like:
s = render_to_string :file => 'layouts/question.xml'
File.open('fixed.xml','w'){|f| f.write s}
render :text => s
Another approach :
send_data fixed, :type => 'text/xml; charset=UTF-8;', :disposition =>
"attachment; filename=fixed.xml"

Resources