How to send a dynamically generated file in a rails app

Ricardo Amores picture Ricardo Amores · Feb 4, 2010 · Viewed 9k times · Source

I'm trying to serve a dynamically generated files in a rails app, so when the user clicks a specific link, the file is generated and sent to the client using send_data.

The file is not intended to be reused: is a short text file and regenerating should be really inexpensive as it won't be donwloaded that much; but if it is necessary or convenient I could store it in the database so is only generated once.

First, I would like to generate the file in memory, and send it in the controller. I'm trying to archive something like this:

def DownloadsController < ApplicationController
  def project_file
    project = Project.find(params[:id])
    send_data project.generate_really_simply_text_file_report
  end
end

But i don't know how to generate a stream in memory, so no file is created in the file system.

Another option would be generating the file with a random name in the rails app tmp directory and send it from ther, but then the file will be kept there, which is something I would prefer not to happen.

Edit: If I'm not mistaken, send_file blocks the petition until the file is sent, so it could work...

Any other advices or opinions?

Thanks in advance

Answer

Lucas picture Lucas · Feb 4, 2010

If it's a simple problem as you describe it, a simple solution like that will do. Just don't forget the :filename option, otherwise the file will be named as "project_file".

  def project_file
    project = Project.find(params[:id])
    send_data project.generate_really_simply_text_file_report, :filename => "#{project.name}.txt"
  end

Edit:

your project#generate_really_simply_text_file_report should return either the binary data, the path for the file or a raw String.

  def download
    content = "chunky bacon\r\nis awesome"
    send_data content,  :filename => "bacon.txt" 
  end