I want to send an XML file when get request is made
here is my my xml file
<forms>
<form url="https://opendatakit.appspot.com/formXml?formId=CascadingSelect">Cascading Select Form</form>
<form url="https://opendatakit.appspot.com/formXml?formId=widgets">Widgets</form>
</forms>
this is my url
http://localhost:3000/forms/formlist
here is my ruby controller to send a xml
respond_to :xml
def formlist
respond_to do |format|
format.xml {//what should I write here to send formlist.xml}
end
end
here is route.rb
get 'forms/formlist' => 'forms#formlist'
but its not sending xml file giving error code something 422
Please help me
Thanks in advance.
Add .xml to url: http://localhost:3000/forms/formlist.xml
Then simply render your file:
def formlist
respond_to do |format|
format.xml { render '/path/to/formlist.xml' }
end
end
Instead of adding .xml to url you can write your route as this:
get 'forms/formlist' => 'forms#formlist', defaults: { format: 'xml' }
so every request without MIME type will be interpreted as xml request
respond_to do |format|
format.xml {//what should I write here to send formlist.xml}
end
You don't have to write anything between the braces--if your xml file has the correct name.
The route:
First, your route can be simply:
get "forms/formlist"
By default, rails assumes that a route has the format controller/action.
The action:
Your formlist() action can simply look like this:
def formlist
respond_to :xml
end
The respond_to line is a shortcut for:
respond_to do |format|
format.xml {}
end
In either case, your action will only respond to requests for an xml file; requests for other file types will produce an UnknownFormat error.
The view:
Then create the xml file here:
app/views/forms_controller/formlist.xml.erb
If you don't have any ruby code in your xml file, you can omit the .erb extension.
The url:
To request the xml file, you can use the url:
http://localhost:3000/forms/formlist
...and specify the following header in the request:
Accept: text/xml
For instance:
curl --header 'Accept: text/xml' http://localhost:3000/forms/formlist
Or, as rubykid posted, you can use the url:
http://localhost:3000/forms/formlist.xml
For instance:
curl http://localhost:3000/forms/formlist.xml
In either case, rails understands that the request is asking for an xml file.
respond_to():
By default, an action renders an html file named:
app/views/some_controller/action_name.html.erb
The default rendering can be changed with respond_to() and/or render().
For example, respond_to :xml will render the file:
app/views/some_controller/action_name.xml.erb
...which in your case will be:
app/views/forms_controller/formslist.xml.erb
If you want to render a different xml file, only then do you need to use the block form of respond_to() and write something inside the braces:
respond_to do |format|
format.xml {render ...}
end
In that case, see the Rails Guide on rendering for what you can do with render().
For completeness sake, the shortcut:
respond_to :xml, :json
...is equivalent to:
respond to do |format|
format.xml {}
format.json {}
end
Another option:
If the xml file is a static file, i.e. its content never changes, and you want to make it publicly available to anybody, you can put it in the public/ folder. For instance, if you name the xml file:
public/data.xml
...then anyone can request the xml file with the url:
http://localhost:3000/data.xml
Related
I am using devise in my ruby on rails application.
I am calling following endpoint from a laptop web browser
https://myaddress/users/sign_in
It works well, but when I hit the same endpoint in mobile device it sends the request with header accept as Accept: image/*;q=0.8
Now server responds with 406 not acceptable. How can I force devise gems to accept request which may contain header accept with value image/*;q=0.8
I am not sure why you want to respond to an endpoint requesting an image, but it seems to me that you're looking for respond_to. See also this answer.
I'd guess you want to respond to "any". To support image MIME types, you can find an example here (emphasis mine):
If you need to use a MIME type which isn't supported by default, you
can register your own handlers in config/initializers/mime_types.rb as
follows.
Mime::Type.register "image/jpg", :jpg
respond_to also allows you to specify a common block for different
formats by using any:
def index #people = Person.all
respond_to do |format|
format.html
format.any(:xml, :json) { render request.format.to_sym => #people } end end
In the example above, if the format is xml, it will render:
render xml: #people
Or if the format is json:
render json: #people
any can also be used with no arguments, in which case it will be used
for any format requested by the user:
respond_to do |format| format.html format.any { redirect_to
support_path } end
Formats can have different variants.
I have the option in my app to render a XML version of an invoice. To do this, I use a separate class, because it has some complicated calculations. This works fine and it renders the XML nicely in the browser.
However, I prefer to have it downloaded as file instead. How can I achieve this?
In the controller I now have this:
def show
#invoice = Invoice.find(params[:id])
respond_to do |format|
format.xml { render xml: #invoice.render_xml }
end
end
I know you can add options to get it downloaded:
filename: 'mydoc.xml', type: "application/xml", disposition: 'attachment'
But how do I combine it with my specific code?
Change render in your controller to send_data, and add the options that you have in your question. http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_data
Ruby on Rails Question:
Inside the controller you have seven REST actions. Almost all of them have respond to do format xml/html or json. I have no idea what this means. Can you please explain it's purpose.
For example:
def index
#tweets = Tweet.all
respond_to do |format|
format.html
format.json { render json: #tweets }
end
end
What is the purpose of the "respond to" part that contains the html and json? What do these formats do?
Also, what is the difference between xml and html? Sometimes I see xml and other times html.
Thank you
Its just a way of telling your controller how to respond to different request types. For example your client could want html or xml information from you:
def index
#people = Person.find(:all)
respond_to do |format|
format.html
format.xml { render :xml => #people.to_xml }
end
end
What that says is, "if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format." (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to
I know that if I have a url like
mysite/posts/1
The default type returned to me is html. I can get an xml version of the resource by just doing
mysite/posts/1.xml
But how do I get a json version? Is the following supposed to work?
mysite/posts/1.json
Reason I ask is because it doesn't seem to be working. So I figured I should find out if it's "supposed" to work this way before investigating further.
You're doing it right, but if the Controller isn't setup to respond to json requests you won't get anything. You'll have a respond_to block like this:
respond_to do |format|
format.html
format.xml { render :xml => #model_var.to_xml }
format.json { render :json => #model_var.to_json } #without this line, .json requests will go unanswered by the web server.
end
I'm a newcomer to Rails, and have been following the tutorial on the rails webpage.
Using the scaffold instruction to create a "post" model, I found that the new action in the controller has a special directive for XML format:
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
I can't see the reasoning for supporting an XML request when creating a new post. Browsing to /posts/new.xml returns nothing. What is the purpose of this?
The reasoning for it behind the new action is simply to provide a xml client with the default data (or something else if you want).
The format directive is being used by all routes, and you don't need to support a format unless you want to.
The above code could might as well have looked like:
respond_to do |format|
format.html # renders new.html.erb
format.xml { render :xml => {:message => "XML is not supported"} }
format.json { render :text => #post.to_jsonĀ }
format.js # renders new.js.erb
end
Also, this is not limited to the new action, but is available in all your actions. The format to use is either taken from the url (if the route is set up to use it), or from the HTTP-Accept header that the browser sends.