Rails Restful downloads - ruby-on-rails

I want some users to be able to download data in a yaml file.
I see that you can do this with
send-file (but uses a lot of resources)
direct link_to the file in public folder (not good for me since the file is generated so the request needs to go to a controller.
restful url via controller (this method is partially explained in http://guides.rubyonrails.org/action_controller_overview.html but not enough to get it working!)
I followed this and tried something like
def show
#client = Client.find(params[:id])
respond_to do |format|
format.html
format.yml { render :yml => #client.redis_to_file }
end
end
redis_to_file returns a string with the yaml data
in config mime_types.rb
Mime::Type.register "x-yaml", :yml
then access like
clients/5.yml
All I get is "invalid template". (It's correct, I don't have a yml template in my views.)
Any clues about how to do this so that it works is greatly appreciated.

Try this:
respond_to do |format|
format.html
format.yml { send_data #client.redis_to_file, :type => 'x-yaml' }
end
There are more options in the Docs

Related

Multiple render error in rails app while generating pdf file via wicked pdf

I'm using wicked PDF in my rails app to generate PDF. and that is done by a private function generate_pdf in my controler becase after the purchase process i want to generate that pdf and then mailer function to send that pdf to user.
error
Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
code is something lie this.
def place_order
... some code
download_new_pdf(#pur)
UserMailer.confirm_order(#pur).deliver
format.html { redirect_to(:action=>'order_confirmed/'+#pur[:id].to_s) }
end
and the helper function will be
def download_new_pdf(id)
#my_ticket = Purchase.find(id)
#event = Event.find(#my_ticket[:event_id])
render :pdf => "#{#my_ticket[:random_no]}.pdf",
:template => 'tickets/download_invoice.html.erb',
:save_to_file => Rails.root.join('public/data/docs', "#{#my_ticket[:random_no]}.pdf")
end
place_order will do all the DB stuff and at the end generate pdf, send mail and redirect to conformation page. But here it's giving me multiple render error coz of
format.html { redirect_to(:action=>'order_confirmed/'+#pur[:id].to_s) }
and
render :pdf => "#{#my_ticket[:random_no]}.pdf",
:template => 'tickets/download_invoice.html.erb',
:save_to_file => Rails.root.join('public/data/docs', "#{#my_ticket[:random_no]}.pdf")
i tried putting and return but still no luck,Any help would be appreciated. Thanks !!!
Your error is simple. You are render in download_new_pdf and redirecting in place_orderat the same time. It looks like you need to create the pdf file and store in the file system, not to show it immediately to the user, so, check the readme, here is explained how to just create the PDF and don't render it to the client

XLS Format in Ruby on Rails Resources

In an RoR application, I would like the index resource to download an xls file.
Currently, I can get the file to download but it requires a link to a path I created like so
link_to subscribers_path(:format => :xls)
Ideally like the subscribers_path on it's own to add the format xls, and I don't want a view in html format with index.
My file structure
/subscribers
index.html.erb
index.xls.erb
and my controller code
def index
#subscribers = Subscriber.all
respond_to do |format|
format.html
format.xls #{send_data #subscribers.to_csv(col_sep: "/t")}
end
end
I tried to remove html to see if it would just default to another path but it says unknownformat error. I also tried to remove the index.html.erb file to see if would fallback to another format of the same name, but that didn't work.
Hopefully my objective is clear: How do I use the resource index path to link with xls instead of html format?
First, to clarify things: Yes, Rails does fully support XLS.
To use it just put the following line under config/initializers/mime_types.rb:
Mime::Type.register "application/xls", :xls
Then, as the author did it, change the format to xls and create an index.xls.erb
Now, to answer your question, there is a number of ways:
The first thing I thought of, was to just change the request format. In your controller:
class SubscriberController < ActionController::Base
before_filter :change_format
def index
#subscribers = Subscriber.all
respond_to do |format|
format.xls #{send_data #subscribers.to_csv(col_sep: "/t")}
end
end
private
def change_format
request.format = "xls"
end
end
There should also be a dozen other ways to do this, but I would prefer this one.

Write object to XML file (specify my own file name)

So there's the basic function like this ....
def show
#position = Position.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #position }
end
end
and if you go to, say, http://localhost/(position_id).xml then you will see the xml... But I wish to have a standard xml filename that I can write the object details to because I want to access it from outside rails. I am very new to rails and have not programmed in a while...seems like this should be easy, right ? So I just want to have a file created with a name like my_xml.xml for all the objects, rather than 1.xml, 2.xml, (id).xml, etc.
Thanks for the help !
I met similar questions, here is my solution(I am a newbie):
I added below in routes.rb:
resources do
collection do
get 'my_xml'
end
end
Then added the my_xml action in controller. In my_xml action, assemble all data, and format it to xml via to_xml method.
No sure whether above is useful for you. Hope it helpful.

Rails: How to create a file from a controller and save it in the server?

For some strange reason I need to save a file (normally downloaded directly) in the server. In my case I have a PDF file created with PDFKit that I need to keep.
# app/controllers/reports_controller.rb
def show
#report = Report.find(params[:id])
respond_to do |format|
format.pdf { render :text => PDFKit.new(report_url(#report)).to_pdf }
end
end
If I go to reports/1.pdf I get the report I am expecting but I want to keep it in the server.
Is there a Raily way to save a file in the server from a respond to?
Just a quick note before I get to the actual answer: It looks like you're passing a fully-qualified URL (report_url(#report)) to PDFKit.new, which is a waste--it means PDFKit has to make a request to the web server, which in turn needs to go through Rails' router and so on down the line to fetch the contents of the page. Instead you should just render the page inside your controller with render_to_string and pass it to PDFKit.new, since it will accept an HTML string. Keeping that in mind...
This is covered in the "Usage" section of PDFKit's README. You would do something like this:
def show
#report = Report.find(params[:id])
kit = PDFKit.new render_to_string(#report) # pass any options that the
pdf_file = kit.to_file '/some/file/path.pdf' # renderer needs here (same
# options as `render`).
# and if you still want to send it to the browser...
respond_to do |format|
format.pdf { render :file => pdf_file.path }
end
end

How can I access data from a Ruby on Rails application externally?

I'm trying to work with the data in my Rails application from within a separate Ruby script.
I read this forum post in which some people suggest that the best way to work with your data is to encapsulate the database within one application, and then have this application provide an API for working with that data. Because it's apparently bad to integrate your database into several different applications.
Well, now I want to work with some data from my Rails app from another script, but on the same system. How can I achieve this?
I might want to work with the data from my Rails app remotely in the future, but also from a script. I'm assuming this might require JSON or SOAP, but I would like to know before I go researching it.
Have you take a look at ActiveResource? It's specifically designed to expose data from a Rails model to another Rails app over HTTP.
Since Ruby on Rails follows REST, your application is, by default, it's own API. For example, say you have the following controller:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
respond_to do |format|
format.html
format.xml { render :xml => #user}
format.js
end
end
def index
#users = User.all
respond_to do |format|
format.html
format.xml { render :xml => #users}
format.js
end
end
end
Now, when hitting that controller via the web browser, it will render your views as you would expect. For example:
GET /users/1 => /app/views/users/show.html.erb
GET /users => /app/views/users/index.html.erb
However, if you change your requests to be something like:
GET /users/1.xml
GET /users.xml
You'll be returned XML data instead of your HTML views. You can now access this data from any other application by using some sort of REST Client, or simply by calling cURL from any command line.
You can append any extension to the end of your URL, and it will find the appropriate respond_to section.
Accessing the data is simple too, just make a request to your application using something like HTTParty. Look at the examples, they're pretty good.

Resources